diff --git a/.ci.yaml b/.ci.yaml index 0cc83481ae62..3310b3129aaf 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -292,10 +292,10 @@ targets: timeout: 30 properties: target_file: analyze_legacy.yaml - channel: "3.22.3" + channel: "3.24.5" env_variables: >- { - "CHANNEL": "3.22.3" + "CHANNEL": "3.24.5" } - name: Linux analyze_legacy N-2 @@ -303,10 +303,10 @@ targets: timeout: 30 properties: target_file: analyze_legacy.yaml - channel: "3.19.6" + channel: "3.22.3" env_variables: >- { - "CHANNEL": "3.19.6" + "CHANNEL": "3.22.3" } - name: Linux_android custom_package_tests master diff --git a/.ci/flutter_master.version b/.ci/flutter_master.version index e0822338d97d..92e8b3ad0db8 100644 --- a/.ci/flutter_master.version +++ b/.ci/flutter_master.version @@ -1 +1 @@ -456366232af95b5cc447b7c42d0d5ef928347c45 +29a6c648ca4d2b813a6787644fdfe20421a2570a diff --git a/.ci/flutter_stable.version b/.ci/flutter_stable.version index 7b7e72bcc6c8..c2957055b002 100644 --- a/.ci/flutter_stable.version +++ b/.ci/flutter_stable.version @@ -1 +1 @@ -dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 +8495dee1fd4aacbe9de707e7581203232f591b2f diff --git a/.ci/targets/repo_checks.yaml b/.ci/targets/repo_checks.yaml index 090548718e8a..7f7dbe1f249b 100644 --- a/.ci/targets/repo_checks.yaml +++ b/.ci/targets/repo_checks.yaml @@ -28,7 +28,7 @@ tasks: script: .ci/scripts/tool_runner.sh args: - "pubspec-check" - - "--min-min-flutter-version=3.19.0" + - "--min-min-flutter-version=3.22.0" - "--allow-dependencies=script/configs/allowed_unpinned_deps.yaml" - "--allow-pinned-dependencies=script/configs/allowed_pinned_deps.yaml" always: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 53ed01fbf7ca..5ce98de58117 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -105,6 +105,20 @@ updates: open-pull-requests-limit: 10 labels: - "autosubmit" + groups: + test-dependencies: + patterns: + - "androidx.test:*" + - "io.mockk:mockk:*" + - "junit:junit" + - "org.mockito:*" + - "org.robolectric:*" + gradle-plugin: + patterns: + - "org.jetbrains.kotlin:kotlin-gradle-plugin" + androidx: + patterns: + - "androidx.annotation:annotation" ignore: - dependency-name: "com.android.tools.build:gradle" update-types: ["version-update:semver-minor", "version-update:semver-patch"] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b8b866e72f34..84bf40686db4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: # the change if it doesn't. run: | cd $HOME - git clone https://github.com/flutter/flutter.git --depth 1 -b 3.24.0 _flutter + git clone https://github.com/flutter/flutter.git --depth 1 -b 3.27.0 _flutter echo "$HOME/_flutter/bin" >> $GITHUB_PATH cd $GITHUB_WORKSPACE # Checks out a copy of the repo. diff --git a/packages/animations/CHANGELOG.md b/packages/animations/CHANGELOG.md index 76db6b8ed283..dcbed7e7cc05 100644 --- a/packages/animations/CHANGELOG.md +++ b/packages/animations/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 2.0.11 diff --git a/packages/animations/example/pubspec.yaml b/packages/animations/example/pubspec.yaml index 812702238da7..433d849800d5 100644 --- a/packages/animations/example/pubspec.yaml +++ b/packages/animations/example/pubspec.yaml @@ -6,8 +6,8 @@ publish_to: none version: 0.0.1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: animations: diff --git a/packages/animations/pubspec.yaml b/packages/animations/pubspec.yaml index bc208969964e..b697723d18e5 100644 --- a/packages/animations/pubspec.yaml +++ b/packages/animations/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.0.11 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index d018f4941993..f0de02ef0cd8 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 0.11.0+2 * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. diff --git a/packages/camera/camera/example/android/app/build.gradle b/packages/camera/camera/example/android/app/build.gradle index 9e2d6373e872..5e7489854967 100644 --- a/packages/camera/camera/example/android/app/build.gradle +++ b/packages/camera/camera/example/android/app/build.gradle @@ -1,3 +1,9 @@ +plugins { + id "com.android.application" + id "org.jetbrains.kotlin.android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) { } } -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' @@ -21,9 +22,6 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -apply plugin: 'com.android.application' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { namespace 'io.flutter.plugins.cameraexample' compileSdk flutter.compileSdkVersion @@ -32,7 +30,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.cameraexample" minSdkVersion flutter.minSdkVersion - targetSdkVersion 28 + targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/camera/camera/example/android/app/src/main/AndroidManifest.xml b/packages/camera/camera/example/android/app/src/main/AndroidManifest.xml index cef23162ddb6..a6879cf032d5 100644 --- a/packages/camera/camera/example/android/app/src/main/AndroidManifest.xml +++ b/packages/camera/camera/example/android/app/src/main/AndroidManifest.xml @@ -7,6 +7,7 @@ plugins.load(stream) } -} - -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory + repositories { + google() + mavenCentral() + gradlePluginPortal() + } } // See https://github.com/flutter/flutter/blob/master/docs/ecosystem/Plugins-and-Packages-repository-structure.md#gradle-structure for more info. -buildscript { - repositories { - maven { - url "https://plugins.gradle.org/m2/" - } - } - dependencies { - classpath "gradle.plugin.com.google.cloud.artifactregistry:artifactregistry-gradle-plugin:2.2.1" - } +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "8.5.1" apply false + id "org.jetbrains.kotlin.android" version "1.9.0" apply false + id "com.google.cloud.artifactregistry.gradle-plugin" version "2.2.1" + } -apply plugin: "com.google.cloud.artifactregistry.gradle-plugin" + +include ":app" diff --git a/packages/camera/camera/example/integration_test/camera_test.dart b/packages/camera/camera/example/integration_test/camera_test.dart index 1c5c8526c733..d981a4e8d971 100644 --- a/packages/camera/camera/example/integration_test/camera_test.dart +++ b/packages/camera/camera/example/integration_test/camera_test.dart @@ -53,49 +53,6 @@ void main() { actual.longestSide == expectedSize.longestSide; } - // This tests that the capture is no bigger than the preset, since we have - // automatic code to fall back to smaller sizes when we need to. Returns - // whether the image is exactly the desired resolution. - Future testCaptureImageResolution( - CameraController controller, ResolutionPreset preset) async { - final Size expectedSize = presetExpectedSizes[preset]!; - - // Take Picture - final XFile file = await controller.takePicture(); - - // Load picture - final File fileImage = File(file.path); - final Image image = await decodeImageFromList(fileImage.readAsBytesSync()); - - // Verify image dimensions are as expected - expect(image, isNotNull); - return assertExpectedDimensions( - expectedSize, Size(image.height.toDouble(), image.width.toDouble())); - } - - testWidgets('Capture specific image resolutions', - (WidgetTester tester) async { - final List cameras = await availableCameras(); - if (cameras.isEmpty) { - return; - } - for (final CameraDescription cameraDescription in cameras) { - bool previousPresetExactlySupported = true; - for (final MapEntry preset - in presetExpectedSizes.entries) { - final CameraController controller = - CameraController(cameraDescription, preset.key); - await controller.initialize(); - final bool presetExactlySupported = - await testCaptureImageResolution(controller, preset.key); - assert(!(!previousPresetExactlySupported && presetExactlySupported), - 'The camera took higher resolution pictures at a lower resolution.'); - previousPresetExactlySupported = presetExactlySupported; - await controller.dispose(); - } - } - }); - // This tests that the capture is no bigger than the preset, since we have // automatic code to fall back to smaller sizes when we need to. Returns // whether the image is exactly the desired resolution. diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index 5dd02b696866..9f37495145e1 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the camera plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: camera: diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 0b8ebb4a3b5c..fb4e49510968 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.11.0+2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/camera/camera_android/example/android/app/build.gradle b/packages/camera/camera_android/example/android/app/build.gradle index 9e2d6373e872..5e7489854967 100644 --- a/packages/camera/camera_android/example/android/app/build.gradle +++ b/packages/camera/camera_android/example/android/app/build.gradle @@ -1,3 +1,9 @@ +plugins { + id "com.android.application" + id "org.jetbrains.kotlin.android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) { } } -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' @@ -21,9 +22,6 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -apply plugin: 'com.android.application' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { namespace 'io.flutter.plugins.cameraexample' compileSdk flutter.compileSdkVersion @@ -32,7 +30,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.cameraexample" minSdkVersion flutter.minSdkVersion - targetSdkVersion 28 + targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/camera/camera_android/example/android/app/src/main/AndroidManifest.xml b/packages/camera/camera_android/example/android/app/src/main/AndroidManifest.xml index cef23162ddb6..a6879cf032d5 100644 --- a/packages/camera/camera_android/example/android/app/src/main/AndroidManifest.xml +++ b/packages/camera/camera_android/example/android/app/src/main/AndroidManifest.xml @@ -7,6 +7,7 @@ plugins.load(stream) } -} - -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory + repositories { + google() + mavenCentral() + gradlePluginPortal() + } } // See https://github.com/flutter/flutter/blob/master/docs/ecosystem/Plugins-and-Packages-repository-structure.md#gradle-structure for more info. -buildscript { - repositories { - maven { - url "https://plugins.gradle.org/m2/" - } - } - dependencies { - classpath "gradle.plugin.com.google.cloud.artifactregistry:artifactregistry-gradle-plugin:2.2.1" - } +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "8.5.2" apply false + id "org.jetbrains.kotlin.android" version "1.9.0" apply false + id "com.google.cloud.artifactregistry.gradle-plugin" version "2.2.1" } -apply plugin: "com.google.cloud.artifactregistry.gradle-plugin" + +include ":app" diff --git a/packages/camera/camera_android/example/integration_test/camera_test.dart b/packages/camera/camera_android/example/integration_test/camera_test.dart index 8e1a6ce7f791..2ff36722ef1a 100644 --- a/packages/camera/camera_android/example/integration_test/camera_test.dart +++ b/packages/camera/camera_android/example/integration_test/camera_test.dart @@ -3,12 +3,10 @@ // found in the LICENSE file. import 'dart:io'; -import 'dart:ui'; import 'package:camera_android/camera_android.dart'; import 'package:camera_example/camera_controller.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; -import 'package:flutter/painting.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; @@ -50,50 +48,6 @@ void main() { actual.longestSide == expectedSize.longestSide; } - // This tests that the capture is no bigger than the preset, since we have - // automatic code to fall back to smaller sizes when we need to. Returns - // whether the image is exactly the desired resolution. - Future testCaptureImageResolution( - CameraController controller, ResolutionPreset preset) async { - final Size expectedSize = presetExpectedSizes[preset]!; - - // Take Picture - final XFile file = await controller.takePicture(); - - // Load picture - final File fileImage = File(file.path); - final Image image = await decodeImageFromList(fileImage.readAsBytesSync()); - - // Verify image dimensions are as expected - expect(image, isNotNull); - return assertExpectedDimensions( - expectedSize, Size(image.height.toDouble(), image.width.toDouble())); - } - - testWidgets('Capture specific image resolutions', - (WidgetTester tester) async { - final List cameras = - await CameraPlatform.instance.availableCameras(); - if (cameras.isEmpty) { - return; - } - for (final CameraDescription cameraDescription in cameras) { - bool previousPresetExactlySupported = true; - for (final MapEntry preset - in presetExpectedSizes.entries) { - final CameraController controller = CameraController(cameraDescription, - mediaSettings: MediaSettings(resolutionPreset: preset.key)); - await controller.initialize(); - final bool presetExactlySupported = - await testCaptureImageResolution(controller, preset.key); - assert(!(!previousPresetExactlySupported && presetExactlySupported), - 'The camera took higher resolution pictures at a lower resolution.'); - previousPresetExactlySupported = presetExactlySupported; - await controller.dispose(); - } - } - }); - // This tests that the capture is no bigger than the preset, since we have // automatic code to fall back to smaller sizes when we need to. Returns // whether the image is exactly the desired resolution. diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index 18218256feea..68c5b4218c7c 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.10+1 + +* Removes nonnull annotation from MeteringPointHostApiImpl#getDefaultPointSize. + ## 0.6.10 * Removes logic that explicitly removes `READ_EXTERNAL_STORAGE` permission that may be implied diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/MeteringPointHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/MeteringPointHostApiImpl.java index 36306253ed13..a8775ebb2278 100644 --- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/MeteringPointHostApiImpl.java +++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/MeteringPointHostApiImpl.java @@ -83,7 +83,6 @@ public DisplayOrientedMeteringPointFactory getDisplayOrientedMeteringPointFactor * Returns the default point size of the {@link MeteringPoint} width and height, which is a * normalized percentage of the sensor width/height. */ - @NonNull public float getDefaultPointSize() { return MeteringPointFactory.getDefaultPointSize(); } diff --git a/packages/camera/camera_android_camerax/example/android/app/build.gradle b/packages/camera/camera_android_camerax/example/android/app/build.gradle index 2094aa796f4c..aa54980dd3ba 100644 --- a/packages/camera/camera_android_camerax/example/android/app/build.gradle +++ b/packages/camera/camera_android_camerax/example/android/app/build.gradle @@ -1,3 +1,9 @@ +plugins { + id "com.android.application" + id "org.jetbrains.kotlin.android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) { } } -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' @@ -21,10 +22,6 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { namespace 'io.flutter.plugins.cameraxexample' compileSdk flutter.compileSdkVersion @@ -38,7 +35,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.cameraxexample" minSdkVersion flutter.minSdkVersion - targetSdkVersion 30 + targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/camera/camera_android_camerax/example/android/app/src/main/AndroidManifest.xml b/packages/camera/camera_android_camerax/example/android/app/src/main/AndroidManifest.xml index 1a0da4432332..27ccaae60760 100644 --- a/packages/camera/camera_android_camerax/example/android/app/src/main/AndroidManifest.xml +++ b/packages/camera/camera_android_camerax/example/android/app/src/main/AndroidManifest.xml @@ -6,11 +6,11 @@ android:icon="@mipmap/ic_launcher"> - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/flutter_image/example/macos/Runner/Release.entitlements b/packages/flutter_image/example/macos/Runner/Release.entitlements index 51d323ec35ad..3618034fd14e 100644 --- a/packages/flutter_image/example/macos/Runner/Release.entitlements +++ b/packages/flutter_image/example/macos/Runner/Release.entitlements @@ -5,7 +5,6 @@ com.apple.security.network.client com.apple.security.app-sandbox - - + diff --git a/packages/flutter_image/example/pubspec.yaml b/packages/flutter_image/example/pubspec.yaml index a7a03cb89c89..70ef7e73bd41 100644 --- a/packages/flutter_image/example/pubspec.yaml +++ b/packages/flutter_image/example/pubspec.yaml @@ -6,8 +6,8 @@ publish_to: "none" version: 1.0.0+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: cupertino_icons: ^1.0.2 diff --git a/packages/flutter_image/pubspec.yaml b/packages/flutter_image/pubspec.yaml index d721eb89c37d..458d2506a695 100644 --- a/packages/flutter_image/pubspec.yaml +++ b/packages/flutter_image/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 4.1.11 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/flutter_lints/CHANGELOG.md b/packages/flutter_lints/CHANGELOG.md index a65e7e221228..2724963c3cd9 100644 --- a/packages/flutter_lints/CHANGELOG.md +++ b/packages/flutter_lints/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 5.0.0 * Updates `package:lints` dependency to version 5.0.0, with the following changes: diff --git a/packages/flutter_lints/example/pubspec.yaml b/packages/flutter_lints/example/pubspec.yaml index 472307f440dd..08ee423dbd7d 100644 --- a/packages/flutter_lints/example/pubspec.yaml +++ b/packages/flutter_lints/example/pubspec.yaml @@ -4,7 +4,7 @@ description: A project that showcases how to enable the recommended lints for Fl publish_to: none environment: - sdk: ^3.3.0 + sdk: ^3.4.0 # Add the latest version of `package:flutter_lints` as a dev_dependency. The # lint set provided by this package is activated in the `analysis_options.yaml` diff --git a/packages/flutter_markdown/CHANGELOG.md b/packages/flutter_markdown/CHANGELOG.md index 0c43f4fa88c9..30e4a3804970 100644 --- a/packages/flutter_markdown/CHANGELOG.md +++ b/packages/flutter_markdown/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 0.7.4+3 * Passes a default error builder to image widgets. diff --git a/packages/flutter_markdown/example/pubspec.yaml b/packages/flutter_markdown/example/pubspec.yaml index 390eb0d27f26..f6c1960aa816 100644 --- a/packages/flutter_markdown/example/pubspec.yaml +++ b/packages/flutter_markdown/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the flutter_markdown package. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/flutter_markdown/pubspec.yaml b/packages/flutter_markdown/pubspec.yaml index b78c0dce3ddf..3c8f7b6ffff7 100644 --- a/packages/flutter_markdown/pubspec.yaml +++ b/packages/flutter_markdown/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.7.4+3 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/flutter_migrate/CHANGELOG.md b/packages/flutter_migrate/CHANGELOG.md index 2d132e53fc13..1cbeac241051 100644 --- a/packages/flutter_migrate/CHANGELOG.md +++ b/packages/flutter_migrate/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 0.0.1+4 * Adds `missing_code_block_language_in_doc_comment` lint. diff --git a/packages/flutter_migrate/pubspec.yaml b/packages/flutter_migrate/pubspec.yaml index f1aafdf48cf0..caa3d9403fe5 100644 --- a/packages/flutter_migrate/pubspec.yaml +++ b/packages/flutter_migrate/pubspec.yaml @@ -6,7 +6,7 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ publish_to: none environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: args: ^2.3.1 diff --git a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md index f9c8ebd2d9c8..ee1622e9cb4e 100644 --- a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md +++ b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.24 + +* Updates annotation to 1.9.1. + ## 2.0.23 * Updates Java compatibility version to 11. diff --git a/packages/flutter_plugin_android_lifecycle/android/build.gradle b/packages/flutter_plugin_android_lifecycle/android/build.gradle index 6f897eed0f51..f273e1514131 100644 --- a/packages/flutter_plugin_android_lifecycle/android/build.gradle +++ b/packages/flutter_plugin_android_lifecycle/android/build.gradle @@ -43,7 +43,7 @@ android { } dependencies { - implementation "androidx.annotation:annotation:1.7.0" + implementation "androidx.annotation:annotation:1.9.1" } diff --git a/packages/flutter_plugin_android_lifecycle/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/pubspec.yaml index 0e8bb6653a43..3bd52cf8b4b2 100644 --- a/packages/flutter_plugin_android_lifecycle/pubspec.yaml +++ b/packages/flutter_plugin_android_lifecycle/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_plugin_android_lifecycle description: Flutter plugin for accessing an Android Lifecycle within other plugins. repository: https://github.com/flutter/packages/tree/main/packages/flutter_plugin_android_lifecycle issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_plugin_android_lifecycle%22 -version: 2.0.23 +version: 2.0.24 environment: sdk: ^3.5.0 diff --git a/packages/flutter_template_images/CHANGELOG.md b/packages/flutter_template_images/CHANGELOG.md index 6cf915b7ff90..efc23cd17b13 100644 --- a/packages/flutter_template_images/CHANGELOG.md +++ b/packages/flutter_template_images/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 4.2.1 diff --git a/packages/flutter_template_images/pubspec.yaml b/packages/flutter_template_images/pubspec.yaml index 411d285db25d..737ae29b76a3 100644 --- a/packages/flutter_template_images/pubspec.yaml +++ b/packages/flutter_template_images/pubspec.yaml @@ -5,7 +5,7 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 4.2.1 environment: - sdk: ^3.3.0 + sdk: ^3.4.0 topics: - assets diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index e2f174dbef07..9327b97442bb 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 14.6.2 - Replaces deprecated collection method usage. diff --git a/packages/go_router/example/lib/shell_route.dart b/packages/go_router/example/lib/shell_route.dart index 1628151d9371..7ffc474b0fd3 100644 --- a/packages/go_router/example/lib/shell_route.dart +++ b/packages/go_router/example/lib/shell_route.dart @@ -87,7 +87,7 @@ class ShellRouteExampleApp extends StatelessWidget { }, routes: [ // The details screen to display stacked on the inner Navigator. - // This will cover screen A but not the application shell. + // This will cover screen C but not the application shell. GoRoute( path: 'details', builder: (BuildContext context, GoRouterState state) { diff --git a/packages/go_router/example/pubspec.yaml b/packages/go_router/example/pubspec.yaml index 40a65efc4311..5bcef78c499d 100644 --- a/packages/go_router/example/pubspec.yaml +++ b/packages/go_router/example/pubspec.yaml @@ -4,8 +4,8 @@ version: 3.0.1 publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: adaptive_navigation: ^0.0.4 diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index a5e2e26b3cf6..1113c4cbea93 100644 --- a/packages/go_router/pubspec.yaml +++ b/packages/go_router/pubspec.yaml @@ -6,8 +6,8 @@ repository: https://github.com/flutter/packages/tree/main/packages/go_router issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: collection: ^1.15.0 diff --git a/packages/go_router_builder/CHANGELOG.md b/packages/go_router_builder/CHANGELOG.md index 9367f706ae68..260f6e2d10e6 100644 --- a/packages/go_router_builder/CHANGELOG.md +++ b/packages/go_router_builder/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 2.7.1 diff --git a/packages/go_router_builder/example/pubspec.yaml b/packages/go_router_builder/example/pubspec.yaml index a4d0efc279db..46d64d191886 100644 --- a/packages/go_router_builder/example/pubspec.yaml +++ b/packages/go_router_builder/example/pubspec.yaml @@ -3,7 +3,7 @@ description: go_router_builder examples publish_to: none environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: collection: ^1.15.0 diff --git a/packages/go_router_builder/pubspec.yaml b/packages/go_router_builder/pubspec.yaml index 6686ec3ba126..ef914abf8690 100644 --- a/packages/go_router_builder/pubspec.yaml +++ b/packages/go_router_builder/pubspec.yaml @@ -7,8 +7,8 @@ repository: https://github.com/flutter/packages/tree/main/packages/go_router_bui issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router_builder%22 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: analyzer: ">=5.2.0 <7.0.0" @@ -27,6 +27,7 @@ dev_dependencies: flutter: sdk: flutter go_router: ^14.0.0 + leak_tracker_flutter_testing: ">=3.0.0" test: ^1.20.0 topics: diff --git a/packages/go_router_builder/test/flutter_test_config.dart b/packages/go_router_builder/test/flutter_test_config.dart new file mode 100644 index 000000000000..9907e578b84b --- /dev/null +++ b/packages/go_router_builder/test/flutter_test_config.dart @@ -0,0 +1,13 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; + +Future testExecutable(FutureOr Function() testMain) async { + LeakTesting.enable(); + LeakTracking.warnForUnsupportedPlatforms = false; + await testMain(); +} diff --git a/packages/google_adsense/CHANGELOG.md b/packages/google_adsense/CHANGELOG.md index a8f06137621f..57f202439cce 100644 --- a/packages/google_adsense/CHANGELOG.md +++ b/packages/google_adsense/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.1.1 + +* Adds `AdSenseCodeParameters` configuration object for `adSense.initialize`. +* Adds a 100ms delay to `adBreak` and `showAdFn`, so Flutter tapevents have time + to settle before an H5 Ad takes over the screen. + +## 0.1.0 + +* Adds H5 Games Ads API as `h5` library. + ## 0.0.2 * **Breaking changes**: Reshuffles API exports: diff --git a/packages/google_adsense/README.md b/packages/google_adsense/README.md index c82209d480af..ccecc9285412 100644 --- a/packages/google_adsense/README.md +++ b/packages/google_adsense/README.md @@ -1,150 +1,40 @@ -# google_adsense -[Google AdSense](https://adsense.google.com/intl/en_us/start/) plugin for Flutter Web - -This package initializes AdSense on your website and provides an ad unit `Widget` that can be configured and placed in the desired location in your Flutter web app UI, without having to directly modify the HTML markup of the app directly. - -## Disclaimer: Early Access ⚠️ -This package is currently in early access and is provided as-is. While it's open source and publicly available, it's likely that you'll need to make additional customizations and configurations to fully integrate it with your Flutter Web App. -Please express interest joining Early Access program using [this form](https://docs.google.com/forms/d/e/1FAIpQLSdN6aOwVkaxGdxbVQFVZ_N4_UCBkuWYa-cS4_rbU_f1jK10Tw/viewform) - -## Usage - -### Setup your AdSense account -1. [Make sure your site's pages are ready for AdSense](https://support.google.com/adsense/answer/7299563) -2. [Create your AdSense account](https://support.google.com/adsense/answer/10162) - -### Initialize AdSense -To start displaying ads, initialize AdSense with your [Publisher ID](https://support.google.com/adsense/answer/105516) (only use numbers). - - -```dart -import 'package:google_adsense/experimental/ad_unit_widget.dart'; -import 'package:google_adsense/google_adsense.dart'; - -void main() async { - // Call `initialize` with your Publisher ID (pub-0123456789012345) - // (See: https://support.google.com/adsense/answer/105516) - await adSense.initialize('0123456789012345'); - - runApp(const MyApp()); -} -``` - -### Displaying Auto Ads -In order to start displaying [Auto ads](https://support.google.com/adsense/answer/9261805): - -1. Configure this feature in your AdSense Console. +# Before you start -Auto ads should start showing just with the call to `initialize`, when available. +This package is only intended for use by web **games**. -If you want to display ad units within your app content, continue to the next step +Please apply to the H5 Games Ads beta using [this form][h5-beta-form]. Once +approved, you may use the package. -### Display ad units (`AdUnitWidget`) +**Without approval, your code may not behave as expected, and your AdSense +account may face policy issues.** -To display an Ad unit in your Flutter application: - -1. Create [ad units](https://support.google.com/adsense/answer/9183549) in your AdSense account. - This will provide an HTML snippet, which you need to translate to Dart. -2. Pick the `AdUnitConfiguration` for your ad type: - -| Ad Unit Type | `AdUnitConfiguration` constructor method | -|----------------|--------------------------------------------| -| Display Ads | `AdUnitConfiguration.displayAdUnit(...)` | -| In-feed Ads | `AdUnitConfiguration.inFeedAdUnit(...)` | -| In-article Ads | `AdUnitConfiguration.inArticleAdUnit(...)` | -| Multiplex Ads | `AdUnitConfiguration.multiplexAdUnit(...)` | - -3. The data-attributes from the generated snippet are available through the `AdUnitConfiguration` object. -Their Dart name is created as follows: - -- The `data-` prefix is **removed**. -- `kebab-case` becomes `camelCase` - -The only exception to this is `data-ad-client`, that is passed to `adSense.initialize`, -instead of through an `AdUnitConfiguration` object. - -For example snippet below: - -```html - - -``` -translates into: - - -```dart -// Call `initialize` with your Publisher ID (pub-0123456789012345) -// (See: https://support.google.com/adsense/answer/105516) -await adSense.initialize('0123456789012345'); - -``` +# google_adsense -and: +[Google AdSense](https://adsense.google.com/start/) plugin for Flutter Web. - -```dart - AdUnitWidget( - configuration: AdUnitConfiguration.displayAdUnit( - // TODO: Replace with your Ad Unit ID - adSlot: '1234567890', - // Remove AdFormat to make ads limited by height - adFormat: AdFormat.AUTO, - ), -), -``` +This package provides a way to initialize and use AdSense on your Flutter Web app. +It includes libraries for the following products: -#### `AdUnitWidget` customizations +* [H5 Games Ads](https://adsense.google.com/start/h5-games-ads/) (in beta, please + apply using [this form][h5-beta-form]) +* [AdSense Ad Unit](https://support.google.com/adsense/answer/9183549) Widget + (experimental and invitation-only, not accepting applications now) -To [modify your responsive ad code](https://support.google.com/adsense/answer/9183363?hl=en&ref_topic=9183242&sjid=11551379421978541034-EU): -1. Make sure to follow [AdSense policies](https://support.google.com/adsense/answer/1346295?hl=en&sjid=18331098933308334645-EU&visit_id=638689380593964621-4184295127&ref_topic=1271508&rd=1) -2. Use Flutter instruments for [adaptive and responsive design](https://docs.flutter.dev/ui/adaptive-responsive) +[h5-beta-form]: https://adsense.google.com/start/h5-beta/?src=flutter -For example, when not using responsive `AdFormat` it is recommended to wrap adUnit widget in the `Container` with width and/or height constraints. -Note some [policies and restrictions](https://support.google.com/adsense/answer/9185043?hl=en#:~:text=Policies%20and%20restrictions) related to ad unit sizing: +## Documentation - -```dart -Container( - constraints: - const BoxConstraints(maxHeight: 100, maxWidth: 1200), - padding: const EdgeInsets.only(bottom: 10), - child: AdUnitWidget( - configuration: AdUnitConfiguration.displayAdUnit( - // TODO: Replace with your Ad Unit ID - adSlot: '1234567890', - // Do not use adFormat to make ad unit respect height constraint - // adFormat: AdFormat.AUTO, - ), - ), -), -``` -## Testing and common errors +Check the [Flutter API docs](https://pub.dev/documentation/google_adsense/latest/) +to learn how to: -### Failed to load resource: the server responded with a status of 400 -Make sure to set correct values to adSlot and adClient arguments +* [Initialize AdSense](https://pub.dev/documentation/google_adsense/latest/topics/Initialization-topic.html) +* [Use H5 Games Ads](https://pub.dev/documentation/google_adsense/latest/topics/H5%20Games%20Ads-topic.html) (beta) +* [Display Ad Units](https://pub.dev/documentation/google_adsense/latest/topics/Ad%20Units-topic.html) (experimental) -### Failed to load resource: the server responded with a status of 403 -1. When happening in **testing/staging** environment it is likely related to the fact that ads are only filled when requested from an authorized domain. If you are testing locally and running your web app on `localhost`, you need to: - 1. Set custom domain name on localhost by creating a local DNS record that would point `127.0.0.1` and/or `localhost` to `your-domain.com`. On mac/linux machines this can be achieved by adding the following records to you /etc/hosts file: - `127.0.0.1 your-domain.com` - `localhost your-domain.com` - 2. Specify additional run arguments in IDE by editing `Run/Debug Configuration` or by passing them directly to `flutter run` command: - `--web-port=8080` - `--web-hostname=your-domain.com` -2. When happening in **production** it might be that your domain was not yet approved or was disapproved. Login to your AdSense account to check your domain approval status +## Support -### Ad unfilled +For technical problems with the code of this package, please +[create a Github issue](https://github.com/flutter/flutter/issues/new?assignees=&labels=&projects=&template=9_first_party_packages.yml). -There is no deterministic way to make sure your ads are 100% filled even when testing. Some of the way to increase the fill rate: -- Ensure your ad units are correctly configured in AdSense -- Try setting `adTest` parameter to `true` -- Try setting AD_FORMAT to `auto` (default setting) -- Try setting FULL_WIDTH_RESPONSIVE to `true` (default setting) -- Try resizing the window or making sure that ad unit Widget width is less than ~1200px +For any questions or support, please reach out to your Google representative or +leverage the [AdSense Help Center](https://support.google.com/adsense#topic=3373519). diff --git a/packages/google_adsense/dartdoc_options.yaml b/packages/google_adsense/dartdoc_options.yaml new file mode 100644 index 000000000000..121c548b0607 --- /dev/null +++ b/packages/google_adsense/dartdoc_options.yaml @@ -0,0 +1,13 @@ +dartdoc: + categories: + "Initialization": + markdown: doc/initialization.md + "H5 Games Ads": + markdown: doc/h5.md + "Ad Units": + markdown: doc/ad_unit_widget.md + categoryOrder: + - "Initialization" + - "H5 Games Ads" + - "Ad Units" + showUndocumentedCategories: true diff --git a/packages/google_adsense/doc/ad_unit_widget.md b/packages/google_adsense/doc/ad_unit_widget.md new file mode 100644 index 000000000000..bec5aa1a5c49 --- /dev/null +++ b/packages/google_adsense/doc/ad_unit_widget.md @@ -0,0 +1,140 @@ +# Before you start + +This library is in a closed early access, and the list is closed for now. + +Stay tuned for expanded availability of the Ad Unit Widget for Flutter web. + +# `AdUnitWidget` + +The `experimental/ad_unit_widget.dart` library provides an `AdUnitWidget` that +can be configured and placed in the widget tree of your Flutter web app. + +## Usage + +First, initialize AdSense (see the +[Initialization](https://pub.dev/documentation/google_adsense/latest/topics/Initialization-topic.html) +topic). + +### Displaying Auto Ads + +In order to start displaying [Auto ads](https://support.google.com/adsense/answer/9261805): + +1. Configure this feature in your AdSense Console. + +Auto ads should start showing just with the call to `initialize`, when available. + +If you want to display ad units within your app content, continue to the next steps: + +### Import the widget + +Import the **experimental** `AdUnitWidget` from the package: + + +```dart +import 'package:google_adsense/experimental/ad_unit_widget.dart'; +``` + +### Displaying Ad Units + +To display AdSense Ad Units in your Flutter application layout: + +1. Create [ad units](https://support.google.com/adsense/answer/9183549) + in your AdSense account. This will provide an HTML snippet, which you need to + _translate_ to Dart. +2. The data-attributes from the generated snippet can be translated to Dart with the `AdUnitConfiguration` object. +Their Dart name is created as follows: + - The `data-` prefix is removed. + - `kebab-case` becomes `camelCase` + +The only exception to this is `data-ad-client`, that is passed to `adSense.initialize`, +instead of through an `AdUnitConfiguration` object. + +For example, the snippet below: + +```html + + +``` + +translates into: + + +```dart + AdUnitWidget( + configuration: AdUnitConfiguration.displayAdUnit( + // TODO: Replace with your Ad Unit ID + adSlot: '1234567890', + // Remove AdFormat to make ads limited by height + adFormat: AdFormat.AUTO, + ), +), +``` + +#### **`AdUnitConfiguration` constructors** + +In addition to `displayAdUnit`, there's specific constructors for each supported +Ad Unit type. See the table below: + +| Ad Unit Type | `AdUnitConfiguration` constructor method | +|----------------|--------------------------------------------| +| Display Ads | `AdUnitConfiguration.displayAdUnit(...)` | +| In-feed Ads | `AdUnitConfiguration.inFeedAdUnit(...)` | +| In-article Ads | `AdUnitConfiguration.inArticleAdUnit(...)` | +| Multiplex Ads | `AdUnitConfiguration.multiplexAdUnit(...)` | + + +#### **`AdUnitWidget` customizations** + +To [modify your responsive ad code](https://support.google.com/adsense/answer/9183363?hl=en&ref_topic=9183242&sjid=11551379421978541034-EU): +1. Make sure to follow [AdSense policies](https://support.google.com/adsense/answer/1346295?hl=en&sjid=18331098933308334645-EU&visit_id=638689380593964621-4184295127&ref_topic=1271508&rd=1) +2. Use Flutter instruments for [adaptive and responsive design](https://docs.flutter.dev/ui/adaptive-responsive) + +For example, when not using responsive `AdFormat` it is recommended to wrap adUnit widget in the `Container` with width and/or height constraints. +Note some [policies and restrictions](https://support.google.com/adsense/answer/9185043?hl=en#:~:text=Policies%20and%20restrictions) related to ad unit sizing: + + +```dart +Container( + constraints: + const BoxConstraints(maxHeight: 100, maxWidth: 1200), + padding: const EdgeInsets.only(bottom: 10), + child: AdUnitWidget( + configuration: AdUnitConfiguration.displayAdUnit( + // TODO: Replace with your Ad Unit ID + adSlot: '1234567890', + // Do not use adFormat to make ad unit respect height constraint + // adFormat: AdFormat.AUTO, + ), + ), +), +``` +## Testing and common errors + +### Failed to load resource: the server responded with a status of 400 +Make sure to set correct values to adSlot and adClient arguments + +### Failed to load resource: the server responded with a status of 403 +1. When happening in **testing/staging** environment it is likely related to the fact that ads are only filled when requested from an authorized domain. If you are testing locally and running your web app on `localhost`, you need to: + 1. Set custom domain name on localhost by creating a local DNS record that would point `127.0.0.1` and/or `localhost` to `your-domain.com`. On mac/linux machines this can be achieved by adding the following records to you /etc/hosts file: + `127.0.0.1 your-domain.com` + `localhost your-domain.com` + 2. Specify additional run arguments in IDE by editing `Run/Debug Configuration` or by passing them directly to `flutter run` command: + `--web-port=8080` + `--web-hostname=your-domain.com` +2. When happening in **production** it might be that your domain was not yet approved or was disapproved. Login to your AdSense account to check your domain approval status + +### Ad unfilled + +There is no deterministic way to make sure your ads are 100% filled even when testing. Some of the way to increase the fill rate: +- Ensure your ad units are correctly configured in AdSense +- Try setting `adTest` parameter to `true` +- Try setting AD_FORMAT to `auto` (default setting) +- Try setting FULL_WIDTH_RESPONSIVE to `true` (default setting) +- Try resizing the window or making sure that ad unit Widget width is less than ~1200px diff --git a/packages/google_adsense/doc/h5.md b/packages/google_adsense/doc/h5.md new file mode 100644 index 000000000000..93295ac21c1e --- /dev/null +++ b/packages/google_adsense/doc/h5.md @@ -0,0 +1,158 @@ +# Before you start + +This package is only intended for use by web **games**. + +Please apply to the beta using +[this form](https://adsense.google.com/start/h5-beta/?src=flutter). +Once approved, you may use the package. + +Without approval, your code may not behave as expected, and your AdSense account +may face policy issues. + +# H5 Games Ads + +The `h5.dart` library provides a way to use the +[AdSense Ad Placement API](https://developers.google.com/ad-placement) +to display ads in games on the web. + +[H5 Games Ads](https://adsense.google.com/start/h5-games-ads/) +offers high-performing formats: + +* [Interstitials](https://developers.google.com/ad-placement/apis#interstitials): + Full-screen ads that are displayed at natural breaks in your game, + such as between levels. Users can choose to either click these ads or return + to your game. +* [Rewarded ads](https://developers.google.com/ad-placement/apis#rewarded_ads): + Ads that users can choose to interact with in exchange for in-game rewards. + +H5 Games Ads formats support display ads, TrueView and Bumper video ads. + +_Review the +[Policy for ad units that offer rewards](https://support.google.com/adsense/answer/9121589) +before using Rewarded Ads._ + +## Usage + +First, initialize AdSense (see the +[Initialization](https://pub.dev/documentation/google_adsense/latest/topics/Initialization-topic.html) +topic). + +### Import the H5 Games Ads client + + +```dart +import 'package:google_adsense/h5.dart'; +``` + +This provides an `h5GamesAds` object with two methods: `adBreak` to request ads, +and `adConfig` to configure the ads that are going to be served. + +### Displaying an Interstitial Ad + +To display an Interstitial Ad, call the `adBreak` method with an +`AdBreakPlacement.interstitial`: + + +```dart +h5GamesAds.adBreak( + AdBreakPlacement.interstitial( + type: BreakType.browse, + name: 'test-interstitial-ad', + adBreakDone: _interstitialBreakDone, + ), +); +``` + +#### **Ad break types** + +The following break types are available for `interstitial` ads: + + +| `BreakType` | Description | +|-------------|-------------| +| `start` | Before the app flow starts (after UI has rendered) | +| `pause` | Shown while the app is paused (games) | +| `next` | Ad shown when user is navigating to the next screen | +| `browse` | Shown while the user explores options | + +See the Ad Placement API reference on +[Interstitials](https://developers.google.com/ad-placement/apis#interstitials) +for a full explanation of all the available parameters. + +### Displaying a Rewarded Ad + +_Review the +[Policy for ad units that offer rewards](https://support.google.com/adsense/answer/9121589) +before using Rewarded Ads._ + +To display a Rewarded Ad, call the `adBreak` method with an +`AdBreakPlacement.rewarded`: + + +```dart +h5GamesAds.adBreak( + AdBreakPlacement.rewarded( + name: 'test-rewarded-ad', + beforeReward: _beforeReward, + adViewed: _adViewed, + adDismissed: _adDismissed, + afterAd: _afterAd, + adBreakDone: _rewardedBreakDone, + ), +); +``` + +If a Rewarded ad is available, the `beforeReward` callback will be called with a +`showAdFn` function that you can call to show the Ad when the player wants to +claim a reward. + +When the user fully watches the ad, the `adViewed` callback will be called, and +the reward should be granted. + +If the user dismisses the ad before they're eligible for a reward, the +`adDismissed` callback will be called instead. + +See the Ad Placement API reference on +[Rewarded ads](https://developers.google.com/ad-placement/apis#rewarded_ads) +for a full explanation of all the available parameters, and the +[call sequence for a rewarded ad](https://developers.google.com/ad-placement/apis#call_sequence_for_a_rewarded_ad). + +### The `adBreakDone` callback + +Note that a call to `adBreak` might not show an ad at all. It simply declares a +place where an ad **could** be shown. + +If the API does not have an ad to show it will not call the various before/after +callbacks that are configured. However, if you provide an `adBreakDone` callback, +this will **always** be called, even if an ad is not shown. This allows you to +perform any additional work needed for the placement, such as logging analytics. + +The `adBreakDone` function takes as argument an `AdBreakDonePlacementInfo` object, +which contains a `breakStatus` property. See the `BreakStatus` enum docs for +more information about the possible values. + +### Configuring Ads + +The `adConfig` function communicates the game's current configuration to the Ad +Placement API. It is used to tune the way it preloads ads and to filter the kinds +of ads it requests so they're suitable. + +You can call `adConfig` with an `AdConfigParameters` object at any time, like +this: + + +```dart +h5GamesAds.adConfig( + AdConfigParameters( + // Configure whether or not your game is playing sounds or muted. + sound: SoundEnabled.on, + // Set to `on` so there's an Ad immediately preloaded. + preloadAdBreaks: PreloadAdBreaks.on, + onReady: _onH5Ready, + ), +); +``` + +See the Ad Placement API reference on +[adConfig](https://developers.google.com/ad-placement/apis/adconfig) +for a full explanation of all the available parameters. diff --git a/packages/google_adsense/doc/initialization.md b/packages/google_adsense/doc/initialization.md new file mode 100644 index 000000000000..8b1b777b3022 --- /dev/null +++ b/packages/google_adsense/doc/initialization.md @@ -0,0 +1,53 @@ +# AdSense initialization + +AdSense initialization is the same both for H5 Games Ads and the Ad Unit Widget. + +To initialize AdSense: + +## Setup your AdSense account + +1. [Make sure your site's pages are ready for AdSense](https://support.google.com/adsense/answer/7299563) +2. [Sign up for AdSense](https://support.google.com/adsense/answer/10162) +3. Adhere to the + [AdSense program policies](https://support.google.com/adsense/answer/48182) + while using ads from AdSense, and any specific policies for the ad formats + that you use (for example, there's a specific + [Policy for ad units that offer rewards](https://support.google.com/adsense/answer/9121589).) + +## Configure your Publisher ID + +To start displaying ads, initialize AdSense with your +[Publisher ID](https://support.google.com/adsense/answer/105516) (only use numbers). + + +```dart +import 'package:google_adsense/google_adsense.dart'; + +void main() async { + // Call `initialize` with your Publisher ID (pub-0123456789012345) + // (See: https://support.google.com/adsense/answer/105516) + await adSense.initialize('0123456789012345'); + + runApp(const MyApp()); +} +``` + +## Configure additional AdSense code parameters + +You can pass an `AdSenseCodeParameters` object to the `adSense.initialize` call +to configure additional settings, like a custom channel ID, or for regulatory +compliance. + + +```dart +await adSense.initialize( + '0123456789012345', + adSenseCodeParameters: AdSenseCodeParameters( + adbreakTest: 'on', + adFrequencyHint: '30s', + ), +); +``` + +Check the Google AdSense Help for a complete list of +[AdSense code parameter descriptions](https://support.google.com/adsense/answer/9955214#adsense_code_parameter_descriptions). diff --git a/packages/google_adsense/example/integration_test/core_test.dart b/packages/google_adsense/example/integration_test/core_test.dart index e55f735e2714..4193e414c1b7 100644 --- a/packages/google_adsense/example/integration_test/core_test.dart +++ b/packages/google_adsense/example/integration_test/core_test.dart @@ -11,7 +11,7 @@ import 'package:google_adsense/google_adsense.dart'; import 'package:integration_test/integration_test.dart'; import 'package:web/web.dart' as web; -import 'adsense_test_js_interop.dart'; +import 'js_interop_mocks/adsense_test_js_interop.dart'; const String testClient = 'test_client'; const String testScriptUrl = @@ -33,7 +33,6 @@ void main() async { group('adSense.initialize', () { testWidgets('adds AdSense script tag.', (WidgetTester _) async { final web.HTMLElement target = web.HTMLDivElement(); - // Given await adSense.initialize(testClient, jsLoaderTarget: target); @@ -46,6 +45,39 @@ void main() async { expect(injected.async, true); }); + testWidgets('sets AdSenseCodeParameters in script tag.', + (WidgetTester _) async { + final web.HTMLElement target = web.HTMLDivElement(); + + await adSense.initialize(testClient, + jsLoaderTarget: target, + adSenseCodeParameters: AdSenseCodeParameters( + adHost: 'test-adHost', + admobInterstitialSlot: 'test-admobInterstitialSlot', + admobRewardedSlot: 'test-admobRewardedSlot', + adChannel: 'test-adChannel', + adbreakTest: 'test-adbreakTest', + tagForChildDirectedTreatment: 'test-tagForChildDirectedTreatment', + tagForUnderAgeOfConsent: 'test-tagForUnderAgeOfConsent', + adFrequencyHint: 'test-adFrequencyHint', + )); + + final web.HTMLScriptElement injected = + target.lastElementChild! as web.HTMLScriptElement; + + expect(injected.dataset['adHost'], 'test-adHost'); + expect(injected.dataset['admobInterstitialSlot'], + 'test-admobInterstitialSlot'); + expect(injected.dataset['admobRewardedSlot'], 'test-admobRewardedSlot'); + expect(injected.dataset['adChannel'], 'test-adChannel'); + expect(injected.dataset['adbreakTest'], 'test-adbreakTest'); + expect(injected.dataset['tagForChildDirectedTreatment'], + 'test-tagForChildDirectedTreatment'); + expect(injected.dataset['tagForUnderAgeOfConsent'], + 'test-tagForUnderAgeOfConsent'); + expect(injected.dataset['adFrequencyHint'], 'test-adFrequencyHint'); + }); + testWidgets('Skips initialization if script is already present.', (WidgetTester _) async { final web.HTMLScriptElement script = web.HTMLScriptElement() @@ -64,7 +96,7 @@ void main() async { final web.HTMLElement target = web.HTMLDivElement(); // Write an empty noop object - mockAdsByGoogle(() {}); + mockAdsByGoogle((_) {}); await adSense.initialize(testClient, jsLoaderTarget: target); diff --git a/packages/google_adsense/example/integration_test/experimental_ad_unit_widget_test.dart b/packages/google_adsense/example/integration_test/experimental_ad_unit_widget_test.dart index 12a1231b269a..0127622dd7f6 100644 --- a/packages/google_adsense/example/integration_test/experimental_ad_unit_widget_test.dart +++ b/packages/google_adsense/example/integration_test/experimental_ad_unit_widget_test.dart @@ -14,7 +14,7 @@ import 'package:google_adsense/google_adsense.dart' hide adSense; import 'package:google_adsense/src/adsense/ad_unit_params.dart'; import 'package:integration_test/integration_test.dart'; -import 'adsense_test_js_interop.dart'; +import 'js_interop_mocks/adsense_test_js_interop.dart'; const String testClient = 'test_client'; const String testSlot = 'test_slot'; diff --git a/packages/google_adsense/example/integration_test/h5_test.dart b/packages/google_adsense/example/integration_test/h5_test.dart new file mode 100644 index 000000000000..28ab89b460fb --- /dev/null +++ b/packages/google_adsense/example/integration_test/h5_test.dart @@ -0,0 +1,134 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:js_interop'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_adsense/google_adsense.dart'; +import 'package:google_adsense/h5.dart'; +import 'package:integration_test/integration_test.dart'; +import 'js_interop_mocks/h5_test_js_interop.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + late AdSense adSense; + + setUp(() async { + adSense = AdSense(); + }); + + tearDown(() { + clearAdsByGoogleMock(); + }); + + group('h5GamesAds.adBreak', () { + testWidgets('can do ad breaks', (WidgetTester tester) async { + mockAdsByGoogle( + mockAdBreak(), + ); + await adSense.initialize('_'); + + final AdBreakPlacement adBreakPlacement = AdBreakPlacement( + type: BreakType.reward, + ); + + h5GamesAds.adBreak(adBreakPlacement); + + // Pump frames so we can see what happened with adBreak + await tester.pump(); + // Wait for the async bits of adBreak + await tester.pump(const Duration(milliseconds: 250)); + + expect(lastAdBreakPlacement, isNotNull); + expect(lastAdBreakPlacement!.type?.toDart, 'reward'); + }); + + testWidgets('can call the adBreakDone callback', + (WidgetTester tester) async { + AdBreakDonePlacementInfo? lastPlacementInfo; + + void adBreakDoneCallback(AdBreakDonePlacementInfo placementInfo) { + lastPlacementInfo = placementInfo; + } + + mockAdsByGoogle( + mockAdBreak( + adBreakDonePlacementInfo: AdBreakDonePlacementInfo( + breakName: 'ok-for-tests'.toJS, + ), + ), + ); + await adSense.initialize('_'); + + final AdBreakPlacement adBreakPlacement = AdBreakPlacement( + type: BreakType.reward, + adBreakDone: adBreakDoneCallback, + ); + + h5GamesAds.adBreak(adBreakPlacement); + + // Pump frames so we can see what happened with adBreak + await tester.pump(); + // Wait for the async bits of adBreak + await tester.pump(const Duration(milliseconds: 250)); + + expect(lastPlacementInfo, isNotNull); + expect(lastPlacementInfo!.breakName, 'ok-for-tests'); + }); + + testWidgets('prefixes adBreak name', (WidgetTester tester) async { + mockAdsByGoogle( + mockAdBreak(), + ); + await adSense.initialize('_'); + + final AdBreakPlacement adBreakPlacement = AdBreakPlacement( + type: BreakType.reward, + name: 'my-test-break', + ); + + h5GamesAds.adBreak(adBreakPlacement); + + // Pump frames so we can see what happened with adBreak + await tester.pump(); + // Wait for the async bits of adBreak + await tester.pump(const Duration(milliseconds: 250)); + + expect(lastAdBreakPlacement!.name!.toDart, 'APFlutter-my-test-break'); + }); + }); + + group('h5GamesAds.adConfig', () { + testWidgets('can set up configuration', (WidgetTester tester) async { + bool called = false; + void onReadyCallback() { + called = true; + } + + mockAdsByGoogle( + mockAdConfig(), + ); + await adSense.initialize('_'); + + h5GamesAds.adConfig( + AdConfigParameters( + preloadAdBreaks: PreloadAdBreaks.on, + sound: SoundEnabled.off, + onReady: onReadyCallback, + ), + ); + + // Pump frames so we can see what happened with adConfig + await tester.pump(); + // adConfig doesn't have async bits + await tester.pump(); + + expect(lastAdConfigParameters, isNotNull); + expect(lastAdConfigParameters!.sound!.toDart, 'off'); + expect(lastAdConfigParameters!.preloadAdBreaks!.toDart, 'on'); + expect(called, isTrue); + }); + }); +} diff --git a/packages/google_adsense/example/integration_test/js_interop_mocks/adsbygoogle_js_interop.dart b/packages/google_adsense/example/integration_test/js_interop_mocks/adsbygoogle_js_interop.dart new file mode 100644 index 000000000000..a48c22ecc845 --- /dev/null +++ b/packages/google_adsense/example/integration_test/js_interop_mocks/adsbygoogle_js_interop.dart @@ -0,0 +1,34 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@JS() +library; + +import 'dart:async'; +import 'dart:js_interop'; + +/// A function that looks like `adsbygoogle.push` to our JS-interop. +typedef PushFn = void Function(JSAny? params); + +// window.adsbygoogle uses "duck typing", so let us set anything to it. +@JS('adsbygoogle') +external set _adsbygoogle(JSAny? value); + +/// Mocks `adsbygoogle` [push] function. +/// +/// `push` will run in the next tick (`Timer.run`) to ensure async behavior. +void mockAdsByGoogle(PushFn push) { + _adsbygoogle = { + 'push': (JSAny? params) { + Timer.run(() { + push(params); + }); + }.toJS, + }.jsify(); +} + +/// Sets `adsbygoogle` to null. +void clearAdsByGoogleMock() { + _adsbygoogle = null; +} diff --git a/packages/google_adsense/example/integration_test/adsense_test_js_interop.dart b/packages/google_adsense/example/integration_test/js_interop_mocks/adsense_test_js_interop.dart similarity index 75% rename from packages/google_adsense/example/integration_test/adsense_test_js_interop.dart rename to packages/google_adsense/example/integration_test/js_interop_mocks/adsense_test_js_interop.dart index aff8a4f4a55d..811f7eca9101 100644 --- a/packages/google_adsense/example/integration_test/adsense_test_js_interop.dart +++ b/packages/google_adsense/example/integration_test/js_interop_mocks/adsense_test_js_interop.dart @@ -5,39 +5,19 @@ @JS() library; -import 'dart:async'; import 'dart:js_interop'; import 'dart:ui'; import 'package:google_adsense/src/adsense/ad_unit_params.dart'; import 'package:web/web.dart' as web; +import 'adsbygoogle_js_interop.dart'; -typedef VoidFn = void Function(); - -// window.adsbygoogle uses "duck typing", so let us set anything to it. -@JS('adsbygoogle') -external set _adsbygoogle(JSAny? value); - -/// Mocks `adsbygoogle` [push] function. -/// -/// `push` will run in the next tick (`Timer.run`) to ensure async behavior. -void mockAdsByGoogle(VoidFn push) { - _adsbygoogle = { - 'push': () { - Timer.run(push); - }.toJS, - }.jsify(); -} - -/// Sets `adsbygoogle` to null. -void clearAdsByGoogleMock() { - _adsbygoogle = null; -} +export 'adsbygoogle_js_interop.dart'; typedef MockAdConfig = ({Size size, String adStatus}); /// Returns a function that generates a "push" function for [mockAdsByGoogle]. -VoidFn mockAd({ +PushFn mockAd({ Size size = Size.zero, String adStatus = AdStatus.FILLED, }) { @@ -47,8 +27,8 @@ VoidFn mockAd({ } /// Returns a function that handles a bunch of ad units at once. Can be used with [mockAdsByGoogle]. -VoidFn mockAds(List adConfigs) { - return () { +PushFn mockAds(List adConfigs) { + return (JSAny? _) { final List foundTargets = web.document.querySelectorAll('div[id^=adUnit] ins').toList; diff --git a/packages/google_adsense/example/integration_test/js_interop_mocks/h5_test_js_interop.dart b/packages/google_adsense/example/integration_test/js_interop_mocks/h5_test_js_interop.dart new file mode 100644 index 000000000000..f28498fa68a5 --- /dev/null +++ b/packages/google_adsense/example/integration_test/js_interop_mocks/h5_test_js_interop.dart @@ -0,0 +1,58 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@JS() +library; + +import 'dart:js_interop'; + +import 'package:google_adsense/src/h5/h5.dart'; +import 'adsbygoogle_js_interop.dart'; + +export 'adsbygoogle_js_interop.dart'; + +/// Returns a push implementation that handles calls to `adBreak`. +AdBreakPlacement? lastAdBreakPlacement; +PushFn mockAdBreak({ + AdBreakDonePlacementInfo? adBreakDonePlacementInfo, +}) { + lastAdBreakPlacement = null; + return (JSAny? adBreakPlacement) { + adBreakPlacement as AdBreakPlacement?; + // Leak the adBreakPlacement. + lastAdBreakPlacement = adBreakPlacement; + // Call `adBreakDone` if set, with `adBreakDonePlacementInfo`. + if (adBreakPlacement?.adBreakDone != null) { + assert(adBreakDonePlacementInfo != null); + adBreakPlacement!.adBreakDone! + .callAsFunction(null, adBreakDonePlacementInfo); + } + }; +} + +AdConfigParameters? lastAdConfigParameters; +PushFn mockAdConfig() { + lastAdConfigParameters = null; + return (JSAny? adConfigParameters) { + adConfigParameters as AdConfigParameters?; + // Leak the adConfigParameters. + lastAdConfigParameters = adConfigParameters; + // Call `onReady` if set. + if (adConfigParameters?.onReady != null) { + adConfigParameters!.onReady!.callAsFunction(); + } + }; +} + +extension AdBreakPlacementGettersExtension on AdBreakPlacement { + external JSString? type; + external JSString? name; + external JSFunction? adBreakDone; +} + +extension AdConfigParametersGettersExtension on AdConfigParameters { + external JSString? preloadAdBreaks; + external JSString? sound; + external JSFunction? onReady; +} diff --git a/packages/google_adsense/example/lib/ad_unit_widget.dart b/packages/google_adsense/example/lib/ad_unit_widget.dart new file mode 100644 index 000000000000..7ab1f3801824 --- /dev/null +++ b/packages/google_adsense/example/lib/ad_unit_widget.dart @@ -0,0 +1,116 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ignore_for_file: flutter_style_todos + +import 'package:flutter/material.dart'; + +// #docregion import-widget +import 'package:google_adsense/experimental/ad_unit_widget.dart'; +// #enddocregion import-widget +import 'package:google_adsense/google_adsense.dart'; + +void main() async { + await adSense.initialize('0123456789012345'); + runApp(const MyApp()); +} + +/// The main app. +class MyApp extends StatelessWidget { + /// Constructs a [MyApp] + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + home: const MyHomePage(), + ); + } +} + +/// The home screen +class MyHomePage extends StatefulWidget { + /// Constructs a [HomeScreen] + const MyHomePage({super.key}); + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + title: const Text('AdSense for Flutter demo app'), + ), + body: SingleChildScrollView( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + 'Responsive Ad Constrained by width of 150px:', + ), + Container( + constraints: const BoxConstraints(maxWidth: 150), + padding: const EdgeInsets.only(bottom: 10), + child: + // #docregion adUnit + AdUnitWidget( + configuration: AdUnitConfiguration.displayAdUnit( + // TODO: Replace with your Ad Unit ID + adSlot: '1234567890', + // Remove AdFormat to make ads limited by height + adFormat: AdFormat.AUTO, + ), + ), + // #enddocregion adUnit + ), + const Text( + 'Responsive Ad Constrained by height of 100px and width of 1200px (to keep ad centered):', + ), + // #docregion constraints + Container( + constraints: + const BoxConstraints(maxHeight: 100, maxWidth: 1200), + padding: const EdgeInsets.only(bottom: 10), + child: AdUnitWidget( + configuration: AdUnitConfiguration.displayAdUnit( + // TODO: Replace with your Ad Unit ID + adSlot: '1234567890', + // Do not use adFormat to make ad unit respect height constraint + // adFormat: AdFormat.AUTO, + ), + ), + ), + // #enddocregion constraints + const Text( + 'Fixed 125x125 size Ad:', + ), + Container( + height: 125, + width: 125, + padding: const EdgeInsets.only(bottom: 10), + child: AdUnitWidget( + configuration: AdUnitConfiguration.displayAdUnit( + // TODO: Replace with your Ad Unit ID + adSlot: '1234567890', + isFullWidthResponsive: false, + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/packages/google_adsense/example/lib/h5.dart b/packages/google_adsense/example/lib/h5.dart new file mode 100644 index 000000000000..f40cfef2f99e --- /dev/null +++ b/packages/google_adsense/example/lib/h5.dart @@ -0,0 +1,236 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ignore_for_file: flutter_style_todos + +import 'package:flutter/material.dart'; + +import 'package:google_adsense/google_adsense.dart'; +// #docregion import-h5 +import 'package:google_adsense/h5.dart'; +// #enddocregion import-h5 + +void main() async { + // #docregion initialize-with-code-parameters + await adSense.initialize( + '0123456789012345', + adSenseCodeParameters: AdSenseCodeParameters( + adbreakTest: 'on', + adFrequencyHint: '30s', + ), + ); + // #enddocregion initialize-with-code-parameters + runApp(const MyApp()); +} + +/// The main app. +class MyApp extends StatelessWidget { + /// Constructs a [MyApp] + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + home: const MyHomePage(), + ); + } +} + +/// The home screen +class MyHomePage extends StatefulWidget { + /// Constructs a [HomeScreen] + const MyHomePage({super.key}); + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + bool _h5Ready = false; + bool _adBreakRequested = false; + int _coins = 0; // The counter of rewards + H5ShowAdFn? _showAdFn; + AdBreakDonePlacementInfo? _lastInterstitialInfo; + AdBreakDonePlacementInfo? _lastRewardedInfo; + + @override + void initState() { + super.initState(); + // #docregion adConfig + h5GamesAds.adConfig( + AdConfigParameters( + // Configure whether or not your game is playing sounds or muted. + sound: SoundEnabled.on, + // Set to `on` so there's an Ad immediately preloaded. + preloadAdBreaks: PreloadAdBreaks.on, + onReady: _onH5Ready, + ), + ); + // #enddocregion adConfig + } + + void _onH5Ready() { + setState(() { + _h5Ready = true; + }); + } + + void _requestInterstitialAd() { + // #docregion interstitial + h5GamesAds.adBreak( + AdBreakPlacement.interstitial( + type: BreakType.browse, + name: 'test-interstitial-ad', + adBreakDone: _interstitialBreakDone, + ), + ); + // #enddocregion interstitial + } + + void _interstitialBreakDone(AdBreakDonePlacementInfo info) { + setState(() { + _lastInterstitialInfo = info; + }); + } + + void _requestRewardedAd() { + // #docregion rewarded + h5GamesAds.adBreak( + AdBreakPlacement.rewarded( + name: 'test-rewarded-ad', + beforeReward: _beforeReward, + adViewed: _adViewed, + adDismissed: _adDismissed, + afterAd: _afterAd, + adBreakDone: _rewardedBreakDone, + ), + ); + // #enddocregion rewarded + setState(() { + _adBreakRequested = true; + }); + } + + void _beforeReward(H5ShowAdFn showAdFn) { + setState(() { + _showAdFn = showAdFn; + }); + } + + void _adViewed() { + setState(() { + _showAdFn = null; + _coins++; + }); + } + + void _adDismissed() { + setState(() { + _showAdFn = null; + }); + } + + void _afterAd() { + setState(() { + _showAdFn = null; + _adBreakRequested = false; + }); + } + + void _rewardedBreakDone(AdBreakDonePlacementInfo info) { + setState(() { + _lastRewardedInfo = info; + }); + } + + @override + Widget build(BuildContext context) { + final bool adBreakAvailable = _showAdFn != null; + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + title: const Text('H5 Games for Flutter demo app'), + ), + body: Padding( + padding: const EdgeInsets.all(16), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + TextButton.icon( + onPressed: _h5Ready ? _requestInterstitialAd : null, + label: const Text('Show Interstitial Ad'), + icon: const Icon(Icons.play_circle_outline_rounded), + ), + Text( + 'Interstitial Ad Status:', + style: Theme.of(context).textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + Text('Last Status: ${_lastInterstitialInfo?.breakStatus}'), + const Divider(), + PaddedCard( + children: [ + const Text( + '🪙 Available coins:', + ), + Text( + '$_coins', + style: Theme.of(context).textTheme.displayLarge, + ), + TextButton.icon( + onPressed: + _h5Ready && !adBreakAvailable ? _requestRewardedAd : null, + label: const Text('Prepare Reward'), + icon: const Icon(Icons.download_rounded), + ), + TextButton.icon( + onPressed: _showAdFn, + label: const Text('Watch Ad For 1 Coin'), + icon: const Text('🪙'), + ), + ], + ), + Text( + 'Rewarded Ad Status:', + style: Theme.of(context).textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + Text('Requested? $_adBreakRequested'), + Text('Available? $adBreakAvailable'), + Text('Last Status: ${_lastRewardedInfo?.breakStatus}'), + ], + ), + ), + ); + } +} + +/// A Card with some margin and padding pre-set. +class PaddedCard extends StatelessWidget { + /// Builds a `PaddedCard` with [children]. + const PaddedCard({super.key, required this.children}); + + /// The children for this card. They'll be rendered inside a [Column]. + final List children; + + @override + Widget build(BuildContext context) { + return Card( + margin: const EdgeInsets.only(bottom: 16), + child: Padding( + padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), + child: Column( + children: children, + ), + ), + ); + } +} diff --git a/packages/google_adsense/example/lib/main.dart b/packages/google_adsense/example/lib/main.dart index 88d6f83424ec..f689ee7809eb 100644 --- a/packages/google_adsense/example/lib/main.dart +++ b/packages/google_adsense/example/lib/main.dart @@ -6,17 +6,15 @@ import 'package:flutter/material.dart'; -// #docregion init import 'package:google_adsense/experimental/ad_unit_widget.dart'; +// #docregion init import 'package:google_adsense/google_adsense.dart'; void main() async { -// #docregion init-min // Call `initialize` with your Publisher ID (pub-0123456789012345) // (See: https://support.google.com/adsense/answer/105516) await adSense.initialize('0123456789012345'); - // #enddocregion init-min runApp(const MyApp()); } // #enddocregion init @@ -61,55 +59,12 @@ class _MyHomePageState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Text( - 'Responsive Ad Constrained by width of 150px:', - ), - Container( - constraints: const BoxConstraints(maxWidth: 150), - padding: const EdgeInsets.only(bottom: 10), - child: - // #docregion adUnit - AdUnitWidget( - configuration: AdUnitConfiguration.displayAdUnit( - // TODO: Replace with your Ad Unit ID - adSlot: '1234567890', - // Remove AdFormat to make ads limited by height - adFormat: AdFormat.AUTO, - ), - ), - // #enddocregion adUnit - ), - const Text( - 'Responsive Ad Constrained by height of 100px and width of 1200px (to keep ad centered):', - ), - // #docregion constraints - Container( - constraints: - const BoxConstraints(maxHeight: 100, maxWidth: 1200), - padding: const EdgeInsets.only(bottom: 10), - child: AdUnitWidget( - configuration: AdUnitConfiguration.displayAdUnit( - // TODO: Replace with your Ad Unit ID - adSlot: '1234567890', - // Do not use adFormat to make ad unit respect height constraint - // adFormat: AdFormat.AUTO, - ), - ), - ), - // #enddocregion constraints - const Text( - 'Fixed 125x125 size Ad:', - ), - Container( - height: 125, - width: 125, - padding: const EdgeInsets.only(bottom: 10), - child: AdUnitWidget( - configuration: AdUnitConfiguration.displayAdUnit( - // TODO: Replace with your Ad Unit ID - adSlot: '1234567890', - isFullWidthResponsive: false, - ), + AdUnitWidget( + configuration: AdUnitConfiguration.displayAdUnit( + // TODO: Replace with your Ad Unit ID + adSlot: '1234567890', + // Remove AdFormat to make ads limited by height + adFormat: AdFormat.AUTO, ), ), ], diff --git a/packages/google_adsense/example/web/index.html b/packages/google_adsense/example/web/index.html index e1611098ded7..ae0f4a223d26 100644 --- a/packages/google_adsense/example/web/index.html +++ b/packages/google_adsense/example/web/index.html @@ -1,8 +1,7 @@ + - - diff --git a/packages/google_adsense/lib/experimental/ad_unit_widget.dart b/packages/google_adsense/lib/experimental/ad_unit_widget.dart index 9d165298d40d..ca933eb5a38f 100644 --- a/packages/google_adsense/lib/experimental/ad_unit_widget.dart +++ b/packages/google_adsense/lib/experimental/ad_unit_widget.dart @@ -2,4 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/// {@category Ad Units} +library; + export '../src/adsense/adsense.dart'; diff --git a/packages/google_adsense/lib/google_adsense.dart b/packages/google_adsense/lib/google_adsense.dart index ac0e7ae01c56..4706a7027c3f 100644 --- a/packages/google_adsense/lib/google_adsense.dart +++ b/packages/google_adsense/lib/google_adsense.dart @@ -2,4 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/// {@category Initialization} +library; + export 'src/core/google_adsense.dart'; diff --git a/packages/google_adsense/lib/h5.dart b/packages/google_adsense/lib/h5.dart new file mode 100644 index 000000000000..553ad2d4d0d9 --- /dev/null +++ b/packages/google_adsense/lib/h5.dart @@ -0,0 +1,8 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// {@category H5 Games Ads} +library; + +export 'src/h5/h5.dart'; diff --git a/packages/google_adsense/lib/src/adsense/ad_unit_params.dart b/packages/google_adsense/lib/src/adsense/ad_unit_params.dart index d31a7c2c5fa7..f023f242681e 100644 --- a/packages/google_adsense/lib/src/adsense/ad_unit_params.dart +++ b/packages/google_adsense/lib/src/adsense/ad_unit_params.dart @@ -32,12 +32,12 @@ class AdUnitParams { /// The ads inside a Multiplex ad unit are arranged in a grid. You can specify how many rows and columns you want to show within that grid
/// Sets the number of rows
/// Requires setting [AdUnitParams.MATCHED_CONTENT_UI_TYPE] - static const String MATCHED_CONTENT_ROWS_NUM = 'macthedContentRowsNum'; + static const String MATCHED_CONTENT_ROWS_NUM = 'matchedContentRowsNum'; /// The ads inside a Multiplex ad unit are arranged in a grid. You can specify how many rows and columns you want to show within that grid
/// Sets the number of columns
/// Requires setting [AdUnitParams.MATCHED_CONTENT_UI_TYPE] - static const String MATCHED_CONTENT_COLUMNS_NUM = 'macthedContentColumnsNum'; + static const String MATCHED_CONTENT_COLUMNS_NUM = 'matchedContentColumnsNum'; /// testing environment flag, defaults to kIsDebug static const String AD_TEST = 'adtest'; diff --git a/packages/google_adsense/lib/src/adsense/ad_unit_widget.dart b/packages/google_adsense/lib/src/adsense/ad_unit_widget.dart index 6771c468cc1c..5e25dda6d76b 100644 --- a/packages/google_adsense/lib/src/adsense/ad_unit_widget.dart +++ b/packages/google_adsense/lib/src/adsense/ad_unit_widget.dart @@ -9,7 +9,7 @@ import 'package:flutter/widgets.dart'; import 'package:web/web.dart' as web; import '../core/google_adsense.dart'; -import '../js_interop/adsbygoogle.dart'; +import '../core/js_interop/adsbygoogle.dart'; import '../utils/logging.dart'; import 'ad_unit_configuration.dart'; import 'ad_unit_params.dart'; diff --git a/packages/google_adsense/lib/src/adsense/adsense.dart b/packages/google_adsense/lib/src/adsense/adsense.dart index 07781299c901..2429927cff21 100644 --- a/packages/google_adsense/lib/src/adsense/adsense.dart +++ b/packages/google_adsense/lib/src/adsense/adsense.dart @@ -2,6 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -export 'ad_unit_configuration.dart'; -export 'ad_unit_params.dart' hide AdStatus, AdUnitParams; -export 'ad_unit_widget.dart'; +export 'ad_unit_configuration.dart' show AdUnitConfiguration; +export 'ad_unit_params.dart' show AdFormat, AdLayout, MatchedContentUiType; +export 'ad_unit_widget.dart' show AdUnitWidget; diff --git a/packages/google_adsense/lib/src/adsense/adsense_js_interop.dart b/packages/google_adsense/lib/src/adsense/adsense_js_interop.dart index d3b6fa53bb21..2f3d96d0711a 100644 --- a/packages/google_adsense/lib/src/adsense/adsense_js_interop.dart +++ b/packages/google_adsense/lib/src/adsense/adsense_js_interop.dart @@ -4,12 +4,14 @@ import 'dart:js_interop'; -import '../js_interop/adsbygoogle.dart'; +import '../core/js_interop/adsbygoogle.dart'; /// Adds a `requestAd` method to request an AdSense ad. extension AdsByGoogleExtension on AdsByGoogle { /// Convenience method for invoking push() with an empty object void requestAd() { + // This can't be defined as a named external, because we *must* call push + // with an empty JSObject push(JSObject()); } } diff --git a/packages/google_adsense/lib/src/core/adsense_code_parameters.dart b/packages/google_adsense/lib/src/core/adsense_code_parameters.dart new file mode 100644 index 000000000000..3ab48bfbe25f --- /dev/null +++ b/packages/google_adsense/lib/src/core/adsense_code_parameters.dart @@ -0,0 +1,65 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// Configuration for various settings for game ads. +/// +/// These are set as `data`-attributes in the AdSense script tag. +class AdSenseCodeParameters { + /// Builds an AdSense code parameters object. + /// + /// The following parameters are available: + /// + /// * [adHost]: If you share your revenue with a host platform, use this parameter + /// to specify the host platform. + /// * [admobInterstitialSlot]: If your game runs in a mobile app, use this parameter + /// to request interstitial ads. + /// * [admobRewardedSlot]: If your game runs in a mobile app, use this parameter + /// to request rewarded ads. + /// * [adChannel]: You may include a + /// [custom channel ID](https://support.google.com/adsense/answer/10078316) + /// for tracking the performance of your ads. + /// * [adbreakTest]: Set this parameter to `'on'` to enable testing mode. This + /// lets you test your placements using fake ads. + /// * [tagForChildDirectedTreatment]: Use this parameter if you want to tag your + /// ad requests for treatment as child directed. For more information, refer to: + /// [Tag a site or ad request for child-directed treatment](https://support.google.com/adsense/answer/3248194). + /// * [tagForUnderAgeOfConsent]: Use this parameter if you want to tag your + /// European Economic Area (EEA), Switzerland, and UK ad requests for restricted + /// data processing treatment. For more information, refer to: + /// [Tag an ad request for EEA and UK users under the age of consent (TFUA)](https://support.google.com/adsense/answer/9009582). + /// * [adFrequencyHint]: The minimum average time interval between ads expressed + /// in seconds. If this value is `'120s'` then ads will not be shown more + /// frequently than once every two minutes on average. Note that this is a hint + /// that could be ignored or overridden by a server control in future. + /// + /// For more information about these parameters, check + /// [AdSense code parameter descriptions](https://support.google.com/adsense/answer/9955214#adsense_code_parameter_descriptions). + AdSenseCodeParameters({ + String? adHost, + String? admobInterstitialSlot, + String? admobRewardedSlot, + String? adChannel, + String? adbreakTest, + String? tagForChildDirectedTreatment, + String? tagForUnderAgeOfConsent, + String? adFrequencyHint, + }) : _adSenseCodeParameters = { + if (adHost != null) 'adHost': adHost, + if (admobInterstitialSlot != null) + 'admobInterstitialSlot': admobInterstitialSlot, + if (admobRewardedSlot != null) 'admobRewardedSlot': admobRewardedSlot, + if (adChannel != null) 'adChannel': adChannel, + if (adbreakTest != null) 'adbreakTest': adbreakTest, + if (tagForChildDirectedTreatment != null) + 'tagForChildDirectedTreatment': tagForChildDirectedTreatment, + if (tagForUnderAgeOfConsent != null) + 'tagForUnderAgeOfConsent': tagForUnderAgeOfConsent, + if (adFrequencyHint != null) 'adFrequencyHint': adFrequencyHint, + }; + + final Map _adSenseCodeParameters; + + /// `Map` representation of this configuration object. + Map get toMap => _adSenseCodeParameters; +} diff --git a/packages/google_adsense/lib/src/core/google_adsense.dart b/packages/google_adsense/lib/src/core/google_adsense.dart index 3a56b5af92dc..9f846e33c08e 100644 --- a/packages/google_adsense/lib/src/core/google_adsense.dart +++ b/packages/google_adsense/lib/src/core/google_adsense.dart @@ -2,15 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:js_interop'; - import 'package:flutter/widgets.dart'; import 'package:web/web.dart' as web; -import '../js_interop/adsbygoogle.dart' show adsbygooglePresent; -import '../js_interop/package_web_tweaks.dart'; - import '../utils/logging.dart'; +import 'adsense_code_parameters.dart'; +import 'js_interop/js_loader.dart'; + +export 'adsense_code_parameters.dart' show AdSenseCodeParameters; /// The web implementation of the AdSense API. class AdSense { @@ -18,68 +17,43 @@ class AdSense { /// The [Publisher ID](https://support.google.com/adsense/answer/2923881). late String adClient; - static const String _url = - 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-'; + + /// The (optional) + /// [AdSense Code Parameters](https://support.google.com/adsense/answer/9955214#adsense_code_parameter_descriptions). + AdSenseCodeParameters? adSenseCodeParameters; /// Initializes the AdSense SDK with your [adClient]. /// /// The [adClient] parameter is your AdSense [Publisher ID](https://support.google.com/adsense/answer/2923881). /// + /// The [adSenseCodeParameters] let you configure various settings for your + /// ads. All parameters are optional. See + /// [AdSense code parameter descriptions](https://support.google.com/adsense/answer/9955214#adsense_code_parameter_descriptions). + /// /// Should be called ASAP, ideally in the `main` method. Future initialize( String adClient, { + AdSenseCodeParameters? adSenseCodeParameters, @visibleForTesting bool skipJsLoader = false, @visibleForTesting web.HTMLElement? jsLoaderTarget, }) async { if (_isInitialized) { - debugLog('adSense.initialize called multiple times. Skipping init.'); + debugLog('initialize already called. Skipping.'); return; } this.adClient = adClient; - if (!(skipJsLoader || _sdkAlreadyLoaded(testingTarget: jsLoaderTarget))) { - _loadJsSdk(adClient, jsLoaderTarget); + this.adSenseCodeParameters = adSenseCodeParameters; + if (!skipJsLoader) { + await loadJsSdk( + adClient, + target: jsLoaderTarget, + dataAttributes: adSenseCodeParameters?.toMap, + ); } else { - debugLog('SDK already on page. Skipping init.'); + debugLog('initialize called with skipJsLoader. Skipping loadJsSdk.'); } _isInitialized = true; } - - bool _sdkAlreadyLoaded({ - web.HTMLElement? testingTarget, - }) { - final String selector = 'script[src*=ca-pub-$adClient]'; - return adsbygooglePresent || - web.document.querySelector(selector) != null || - testingTarget?.querySelector(selector) != null; - } - - void _loadJsSdk(String adClient, web.HTMLElement? testingTarget) { - final String finalUrl = _url + adClient; - - final web.HTMLScriptElement script = web.HTMLScriptElement() - ..async = true - ..crossOrigin = 'anonymous'; - - if (web.window.nullableTrustedTypes != null) { - final String trustedTypePolicyName = 'adsense-dart-$adClient'; - try { - final web.TrustedTypePolicy policy = - web.window.trustedTypes.createPolicy( - trustedTypePolicyName, - web.TrustedTypePolicyOptions( - createScriptURL: ((JSString url) => url).toJS, - )); - script.trustedSrc = policy.createScriptURLNoArgs(finalUrl); - } catch (e) { - throw TrustedTypesException(e.toString()); - } - } else { - debugLog('TrustedTypes not available.'); - script.src = finalUrl; - } - - (testingTarget ?? web.document.head)!.appendChild(script); - } } /// The singleton instance of the AdSense SDK. diff --git a/packages/google_adsense/lib/src/js_interop/adsbygoogle.dart b/packages/google_adsense/lib/src/core/js_interop/adsbygoogle.dart similarity index 100% rename from packages/google_adsense/lib/src/js_interop/adsbygoogle.dart rename to packages/google_adsense/lib/src/core/js_interop/adsbygoogle.dart diff --git a/packages/google_adsense/lib/src/core/js_interop/js_loader.dart b/packages/google_adsense/lib/src/core/js_interop/js_loader.dart new file mode 100644 index 000000000000..12b44eacaa0b --- /dev/null +++ b/packages/google_adsense/lib/src/core/js_interop/js_loader.dart @@ -0,0 +1,84 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:js_interop'; +import 'dart:js_interop_unsafe' show JSObjectUnsafeUtilExtension; +import 'package:web/web.dart' as web; + +import '../../utils/logging.dart'; +import 'adsbygoogle.dart' show adsbygooglePresent; +import 'package_web_tweaks.dart'; + +// The URL of the ads by google client. +const String _URL = + 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'; + +/// Loads the JS SDK for [adClient]. +/// +/// [target] can be used to specify a different injection target than +/// `window.document.head`, and is normally used for tests. +/// +/// [dataAttributes] are used to configure the dataset `data-` attributes of the +/// created script element. +Future loadJsSdk( + String adClient, { + web.HTMLElement? target, + Map? dataAttributes, +}) async { + if (_sdkAlreadyLoaded(adClient, target)) { + debugLog('adsbygoogle.js already injected. Skipping call to loadJsSdk.'); + return; + } + + final String scriptUrl = '$_URL?client=ca-pub-$adClient'; + + final web.HTMLScriptElement script = web.HTMLScriptElement() + ..async = true + ..crossOrigin = 'anonymous'; + + if (web.window.nullableTrustedTypes != null) { + final String trustedTypePolicyName = 'adsense-dart-$adClient'; + try { + final web.TrustedTypePolicy policy = web.window.trustedTypes.createPolicy( + trustedTypePolicyName, + web.TrustedTypePolicyOptions( + createScriptURL: ((JSString url) => url).toJS, + )); + script.trustedSrc = policy.createScriptURLNoArgs(scriptUrl); + } catch (e) { + throw TrustedTypesException(e.toString()); + } + } else { + debugLog('TrustedTypes not available.'); + script.src = scriptUrl; + } + + _applyDataAttributes(script, dataAttributes); + + (target ?? web.document.head)!.appendChild(script); +} + +// Applies a map of [attributes] to the `dataset` of [element]. +void _applyDataAttributes( + web.HTMLElement element, + Map? attributes, +) { + attributes?.forEach((String key, String value) { + element.dataset.setProperty(key.toJS, value.toJS); + }); +} + +// Whether the script for [adClient] is already injected. +// +// [target] can be used to specify a different injection target than +// `window.document.head`, and is normally used for tests. +bool _sdkAlreadyLoaded( + String adClient, + web.HTMLElement? target, +) { + final String selector = 'script[src*=ca-pub-$adClient]'; + return adsbygooglePresent || + web.document.querySelector(selector) != null || + target?.querySelector(selector) != null; +} diff --git a/packages/google_adsense/lib/src/js_interop/package_web_tweaks.dart b/packages/google_adsense/lib/src/core/js_interop/package_web_tweaks.dart similarity index 100% rename from packages/google_adsense/lib/src/js_interop/package_web_tweaks.dart rename to packages/google_adsense/lib/src/core/js_interop/package_web_tweaks.dart diff --git a/packages/google_adsense/lib/src/h5/enums.dart b/packages/google_adsense/lib/src/h5/enums.dart new file mode 100644 index 000000000000..318078bdff74 --- /dev/null +++ b/packages/google_adsense/lib/src/h5/enums.dart @@ -0,0 +1,114 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// Adds a `maybe` method to Enum.values to retrieve them by their name +/// without throwing. +extension MaybeEnum on List { + /// Attempts to retrieve an enum of type T by its [name]. + T? maybe(String? name) { + for (final T value in this) { + if (value.name == name) { + return value; + } + } + return null; + } +} + +/// Available types of Ad Breaks. +enum BreakType { + /// Before the app loads (before UI has rendered). + preroll, + + /// Before the app flow starts (after UI has rendered). + start, + + /// When the user pauses the app. + pause, + + /// When the user navigates to the next screen. + next, + + /// When the user explores options. + browse, + + /// Rewarded ad. + reward, +} + +/// The set of [BreakType]s that can be used in [AdBreakPlacement.interstitial]. +const Set interstitialBreakType = { + BreakType.start, + BreakType.pause, + BreakType.next, + BreakType.browse, +}; + +/// Available formats of Ad Breaks. +enum BreakFormat { + /// Used in the middle of content + interstitial, + + /// User gets rewarded for watching the entire ad + reward, +} + +/// Response from AdSense, provided as param of the adBreakDone callback +enum BreakStatus { + /// The Ad Placement API had not initialized. + notReady, + + /// A placement timed out because the Ad Placement API took too long to respond. + timeout, + + /// There was a JavaScript error in a callback. + error, + + /// An ad had not been preloaded yet so this placement was skipped. + noAdPreloaded, + + /// An ad wasn't shown because the frequency cap was applied to this placement. + frequencyCapped, + + /// The user didn't click on a reward prompt before they reached the next placement. + /// + /// That is showAdFn() wasn't called before the next adBreak(). + ignored, + + /// The ad was not shown for another reason. + /// + /// (e.g., The ad was still being fetched, or a previously cached ad was + /// disposed because the screen was resized/rotated.) + other, + + /// The user dismissed a rewarded ad before viewing it to completion. + dismissed, + + /// The ad was viewed by the user. + viewed, + + /// The placement was invalid and was ignored. + /// + /// For instance there should only be one preroll placement per page load, + /// subsequent prerolls are failed with this status. + invalid, +} + +/// Whether ads should always be preloaded before the first call to `adBreak`. +enum PreloadAdBreaks { + /// Always preload. + on, + + /// Leaves the decision up to the Ad Placement API. + auto, +} + +/// Whether the app is plays sounds during normal operations. +enum SoundEnabled { + /// Sound is played. + on, + + /// Sound is never played. + off, +} diff --git a/packages/google_adsense/lib/src/h5/h5.dart b/packages/google_adsense/lib/src/h5/h5.dart new file mode 100644 index 000000000000..8b7e0a96842b --- /dev/null +++ b/packages/google_adsense/lib/src/h5/h5.dart @@ -0,0 +1,59 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import '../core/js_interop/adsbygoogle.dart'; +import 'h5_js_interop.dart'; + +export 'enums.dart' + show BreakFormat, BreakStatus, BreakType, PreloadAdBreaks, SoundEnabled; +export 'h5_js_interop.dart' + show + AdBreakDonePlacementInfo, + AdBreakPlacement, + AdConfigParameters, + H5AdBreakDoneCallback, + H5AdDismissedCallback, + H5AdViewedCallback, + H5AfterAdCallback, + H5BeforeAdCallback, + H5BeforeRewardCallback, + H5OnReadyCallback, + H5ShowAdFn; + +/// A client to request H5 Games Ads (Ad Placement API). +class H5GamesAdsClient { + /// Requests an ad placement to the Ad Placement API. + /// + /// The [placementConfig] defines the configuration of the ad. + void adBreak( + AdBreakPlacement placementConfig, + ) { + // Delay the call to `adBreak` so tap users don't trigger a click on the ad + // on pointerup. This should leaves enough time for Flutter to settle its + // tap events, before triggering the H5 ad. + Timer(const Duration(milliseconds: 100), () { + adsbygoogle.adBreak(placementConfig); + }); + } + + /// Communicates the app's current configuration to the Ad Placement API. + /// + /// The Ad Placement API can use this to tune the way it preloads ads and to + /// filter the kinds of ads it requests so they're suitable (eg. video ads + /// that require sound). + /// + /// Call this function as soon as the sound state of your game changes, as the + /// Ad Placement API may have to request new creatives, and this gives it the + /// maximum amount of time to do so. See `sound` in [AdConfigParameters]. + void adConfig( + AdConfigParameters parameters, + ) { + adsbygoogle.adConfig(parameters); + } +} + +/// The singleton instance of the H5 Games Ads client. +final H5GamesAdsClient h5GamesAds = H5GamesAdsClient(); diff --git a/packages/google_adsense/lib/src/h5/h5_js_interop.dart b/packages/google_adsense/lib/src/h5/h5_js_interop.dart new file mode 100644 index 000000000000..5a0c4342e8e4 --- /dev/null +++ b/packages/google_adsense/lib/src/h5/h5_js_interop.dart @@ -0,0 +1,336 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:js_interop'; + +import 'package:flutter/widgets.dart' show visibleForTesting; + +import '../core/js_interop/adsbygoogle.dart'; +import 'enums.dart'; + +// Used to prefix all the "name"s of the ad placements. +const String _namePrefix = 'APFlutter-'; + +/// Adds H5's `adBreak` and `adConfig` methods to `adSense` to request H5 ads. +extension H5JsInteropExtension on AdsByGoogle { + /// Defines an ad placement configured by [params]. + @JS('push') + external void adBreak(AdBreakPlacement params); + + /// Communicates the app's current [configuration] to the Ad Placement API. + /// + /// The Ad Placement API can use this to tune the way it preloads ads and to + /// filter the kinds of ads it requests so they're suitable (eg. video ads + /// that require sound). + @JS('push') + external void adConfig(AdConfigParameters configuration); +} + +/// Placement configuration object. +/// +/// Used to configure the ad request through the `h5GamesAds.adBreak` method. +/// +/// In addition to a general constructor that takes all possible parameters, this +/// class contains named constructors for the following placement types: +/// +/// * Interstitial (see: [AdBreakPlacement.interstitial]) +/// * Preroll (see: [AdBreakPlacement.preroll]) +/// * Rewarded (see: [AdBreakPlacement.rewarded]) +/// +/// Each constructor will use one or more of the following arguments: +/// +/// {@template pkg_google_adsense_parameter_h5_type} +/// * [type]: The type of the placement. See [BreakType]. +/// {@endtemplate} +/// {@template pkg_google_adsense_parameter_h5_name} +/// * [name]: A name for this particular ad placement within your game. It is an +/// internal identifier, and is not shown to the player. Recommended. +/// {@endtemplate} +/// {@template pkg_google_adsense_parameter_h5_beforeAd} +/// * [beforeAd]: Called before the ad is displayed. The game should pause and +/// mute the sound. These actions must be done synchronously. The ad will be +/// displayed immediately after this callback finishes.. +/// {@endtemplate} +/// {@template pkg_google_adsense_parameter_h5_afterAd} +/// * [afterAd]: Called after the ad is finished (for any reason). For rewarded +/// ads, it is called after either adDismissed or adViewed, depending on +/// player actions +/// {@endtemplate} +/// {@template pkg_google_adsense_parameter_h5_adBreakDone} +/// * [adBreakDone]: Always called as the last step in an `adBreak`, even if +/// there was no ad shown. Takes as argument a `placementInfo` object. +/// See [AdBreakDonePlacementInfo], and: https://developers.google.com/ad-placement/apis/adbreak#adbreakdone_and_placementinfo +/// {@endtemplate} +/// +/// For rewarded placements, the following parameters are also available: +/// +/// {@template pkg_google_adsense_parameter_h5_beforeReward} +/// * [beforeReward]: Called if a rewarded ad is available. The function should +/// take a single argument `showAdFn` which **must** be called to display the +/// rewarded ad. +/// {@endtemplate} +/// {@template pkg_google_adsense_parameter_h5_adDismissed} +/// * [adDismissed]: Called if the player dismisses the ad before it completes. +/// In this case the reward should not be granted. +/// {@endtemplate} +/// {@template pkg_google_adsense_parameter_h5_adViewed} +/// * [adViewed]: Called when the player completes the ad and should be granted +/// the reward. +/// {@endtemplate} +/// +/// For more information about ad units, check +/// [Placement Types](https://developers.google.com/ad-placement/docs/placement-types) +/// documentation and +/// [adBreak parameters](https://developers.google.com/ad-placement/apis/adbreak#adbreak_parameters) +/// in the Ad Placement API docs. +extension type AdBreakPlacement._(JSObject _) implements JSObject { + /// Creates an ad placement configuration that can be passed to `adBreak`. + /// + /// The following parameters are available: + /// + /// {@macro pkg_google_adsense_parameter_h5_type} + /// {@macro pkg_google_adsense_parameter_h5_name} + /// {@macro pkg_google_adsense_parameter_h5_beforeAd} + /// {@macro pkg_google_adsense_parameter_h5_afterAd} + /// {@macro pkg_google_adsense_parameter_h5_beforeReward} + /// {@macro pkg_google_adsense_parameter_h5_adDismissed} + /// {@macro pkg_google_adsense_parameter_h5_adViewed} + /// {@macro pkg_google_adsense_parameter_h5_adBreakDone} + /// + /// This factory can create any type of placement configuration. Read the + /// [Placement Types](https://developers.google.com/ad-placement/docs/placement-types) + /// documentation for more information. + factory AdBreakPlacement({ + required BreakType type, + String? name, + H5BeforeAdCallback? beforeAd, + H5AfterAdCallback? afterAd, + H5BeforeRewardCallback? beforeReward, + H5AdDismissedCallback? adDismissed, + H5AdViewedCallback? adViewed, + H5AdBreakDoneCallback? adBreakDone, + }) { + return AdBreakPlacement._toJS( + type: type.name.toJS, + name: '$_namePrefix${name ?? ''}'.toJS, + beforeAd: beforeAd?.toJS, + afterAd: afterAd?.toJS, + beforeReward: beforeReward != null + ? (JSFunction showAdFn) { + beforeReward(() { + // Delay the call to `showAdFn` so tap users don't trigger a click on the + // ad on pointerup. This should leaves enough time for Flutter to settle + // its tap events, before triggering the H5 ad. + Timer(const Duration(milliseconds: 100), () { + showAdFn.callAsFunction(); + }); + }); + }.toJS + : null, + adDismissed: adDismissed?.toJS, + adViewed: adViewed?.toJS, + adBreakDone: adBreakDone?.toJS, + ); + } + + /// Convenience factory to create a rewarded ad placement configuration. + /// + /// The following parameters are available: + /// + /// {@macro pkg_google_adsense_parameter_h5_name} + /// {@macro pkg_google_adsense_parameter_h5_beforeAd} + /// {@macro pkg_google_adsense_parameter_h5_afterAd} + /// {@macro pkg_google_adsense_parameter_h5_beforeReward} + /// {@macro pkg_google_adsense_parameter_h5_adDismissed} + /// {@macro pkg_google_adsense_parameter_h5_adViewed} + /// {@macro pkg_google_adsense_parameter_h5_adBreakDone} + /// + /// See: https://developers.google.com/ad-placement/apis#rewarded_ads + factory AdBreakPlacement.rewarded({ + String? name, + H5BeforeAdCallback? beforeAd, + H5AfterAdCallback? afterAd, + required H5BeforeRewardCallback? beforeReward, + required H5AdDismissedCallback? adDismissed, + required H5AdViewedCallback? adViewed, + H5AdBreakDoneCallback? adBreakDone, + }) { + return AdBreakPlacement( + type: BreakType.reward, + name: name, + beforeAd: beforeAd, + afterAd: afterAd, + beforeReward: beforeReward, + adDismissed: adDismissed, + adViewed: adViewed, + adBreakDone: adBreakDone, + ); + } + + /// Convenience factory to create a preroll ad configuration. + /// + /// The following parameters are available: + /// + /// {@macro pkg_google_adsense_parameter_h5_adBreakDone} + /// + /// See: https://developers.google.com/ad-placement/apis#prerolls + factory AdBreakPlacement.preroll({ + required H5AdBreakDoneCallback? adBreakDone, + }) { + return AdBreakPlacement( + type: BreakType.preroll, + adBreakDone: adBreakDone, + ); + } + + /// Convenience factory to create an interstitial ad configuration. + /// + /// The following parameters are available: + /// + /// {@macro pkg_google_adsense_parameter_h5_name} + /// {@macro pkg_google_adsense_parameter_h5_beforeAd} + /// {@macro pkg_google_adsense_parameter_h5_afterAd} + /// {@macro pkg_google_adsense_parameter_h5_adBreakDone} + /// + /// See: https://developers.google.com/ad-placement/apis#interstitials + factory AdBreakPlacement.interstitial({ + required BreakType type, + String? name, + H5BeforeAdCallback? beforeAd, + H5AfterAdCallback? afterAd, + H5AdBreakDoneCallback? adBreakDone, + }) { + assert(interstitialBreakType.contains(type), + '$type is not a valid interstitial placement type.'); + return AdBreakPlacement( + type: type, + name: name, + beforeAd: beforeAd, + afterAd: afterAd, + adBreakDone: adBreakDone, + ); + } + + factory AdBreakPlacement._toJS({ + JSString? type, + JSString? name, + JSFunction? beforeAd, + JSFunction? afterAd, + JSFunction? beforeReward, + JSFunction? adDismissed, + JSFunction? adViewed, + JSFunction? adBreakDone, + }) { + return { + if (type != null) 'type': type, + if (name != null) 'name': name, + if (beforeAd != null) 'beforeAd': beforeAd, + if (afterAd != null) 'afterAd': afterAd, + if (beforeReward != null) 'beforeReward': beforeReward, + if (adDismissed != null) 'adDismissed': adDismissed, + if (adViewed != null) 'adViewed': adViewed, + if (adBreakDone != null) 'adBreakDone': adBreakDone, + }.jsify()! as AdBreakPlacement; + } +} + +/// Parameters for the `adConfig` method call. +extension type AdConfigParameters._(JSObject _) implements JSObject { + /// Parameters for the `adConfig` method call. + /// + /// The following parameters are available: + /// + /// * [sound]: Whether the game is currently playing sound. + /// * [preloadAdBreaks]: Whether ads should always be preloaded before the + /// first call to `adBreak`. See: https://developers.google.com/ad-placement/docs/preload-ads + /// * [onReady]: Called when the API has initialized and has finished preloading + /// ads (if you requested preloading using `preloadAdBreaks`). + /// + /// For more information, see: https://developers.google.com/ad-placement/apis/adconfig#adconfig_parameters + factory AdConfigParameters({ + required SoundEnabled? sound, // required because: cl/704928576 + PreloadAdBreaks? preloadAdBreaks, + H5OnReadyCallback? onReady, + }) { + return AdConfigParameters._toJS( + sound: sound?.name.toJS, + preloadAdBreaks: preloadAdBreaks?.name.toJS, + onReady: onReady?.toJS, + ); + } + + factory AdConfigParameters._toJS({ + JSString? sound, + JSString? preloadAdBreaks, + JSFunction? onReady, + }) { + return { + if (sound != null) 'sound': sound, + if (preloadAdBreaks != null) 'preloadAdBreaks': preloadAdBreaks, + if (onReady != null) 'onReady': onReady, + }.jsify()! as AdConfigParameters; + } +} + +/// The parameter passed from the Ad Placement API to the `adBreakDone` callback. +extension type AdBreakDonePlacementInfo._(JSObject _) implements JSObject { + /// Builds an AdBreakDonePlacementInfo object (for tests). + @visibleForTesting + external factory AdBreakDonePlacementInfo({ + JSString? breakType, + JSString? breakName, + JSString? breakFormat, + JSString? breakStatus, + }); + + /// The `type` argument passed to `adBreak`. + BreakType? get breakType => BreakType.values.maybe(_breakType?.toDart); + @JS('breakType') + external JSString? _breakType; + + /// The `name` argument passed to `adBreak`. + String? get breakName => _breakName?.toDart; + @JS('breakName') + external JSString? _breakName; + + /// The format of the break. See [BreakFormat]. + BreakFormat? get breakFormat => + BreakFormat.values.maybe(_breakFormat?.toDart); + @JS('breakFormat') + external JSString? _breakFormat; + + /// The status of this placement. See [BreakStatus]. + BreakStatus? get breakStatus => + BreakStatus.values.maybe(_breakStatus?.toDart); + @JS('breakStatus') + external JSString? _breakStatus; +} + +/// The type of the `showAdFn` function passed to the `beforeReward` callback. +/// +/// This is actually a JSFunction. Do not call outside of the browser. +typedef H5ShowAdFn = void Function(); + +/// The type of the `beforeAd` callback. +typedef H5BeforeAdCallback = void Function(); + +/// The type of the `afterAd` callback. +typedef H5AfterAdCallback = void Function(); + +/// The type of the `adBreakDone` callback. +typedef H5AdBreakDoneCallback = void Function( + AdBreakDonePlacementInfo placementInfo); + +/// The type of the `beforeReward` callback. +typedef H5BeforeRewardCallback = void Function(H5ShowAdFn showAdFn); + +/// The type of the `adDismissed` callback. +typedef H5AdDismissedCallback = void Function(); + +/// The type of the `adViewed` callback. +typedef H5AdViewedCallback = void Function(); + +/// The type of the `onReady` callback. +typedef H5OnReadyCallback = void Function(); diff --git a/packages/google_adsense/pubspec.yaml b/packages/google_adsense/pubspec.yaml index 5739583d2689..26b865b5f4d9 100644 --- a/packages/google_adsense/pubspec.yaml +++ b/packages/google_adsense/pubspec.yaml @@ -2,7 +2,7 @@ name: google_adsense description: A wrapper plugin with convenience APIs allowing easier inserting Google Adsense HTML snippets withing a Flutter UI Web application repository: https://github.com/flutter/packages/tree/main/packages/google_adsense issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_adsense%22 -version: 0.0.2 +version: 0.1.1 environment: sdk: ^3.4.0 diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 75614efbf0db..ef5c348d68b7 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.10.0 * Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/maps_controller.dart index 536adc32f07d..d44aa4d341e2 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/src/maps_controller.dart @@ -21,60 +21,65 @@ void main() { } void runTests() { - testWidgets('testInitialCenterLocationAtCenter', (WidgetTester tester) async { - await tester.binding.setSurfaceSize(const Size(800, 600)); + testWidgets( + 'testInitialCenterLocationAtCenter', + (WidgetTester tester) async { + await tester.binding.setSurfaceSize(const Size(800, 600)); - final Completer mapControllerCompleter = - Completer(); - final Key key = GlobalKey(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: GoogleMap( - key: key, - initialCameraPosition: kInitialCameraPosition, - onMapCreated: (GoogleMapController controller) { - mapControllerCompleter.complete(controller); - }, + final Completer mapControllerCompleter = + Completer(); + final Key key = GlobalKey(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + key: key, + initialCameraPosition: kInitialCameraPosition, + onMapCreated: (GoogleMapController controller) { + mapControllerCompleter.complete(controller); + }, + ), ), - ), - ); - final GoogleMapController mapController = - await mapControllerCompleter.future; - - await tester.pumpAndSettle(); + ); + final GoogleMapController mapController = + await mapControllerCompleter.future; - // TODO(cyanglaz): Remove this after we added `mapRendered` callback, and `mapControllerCompleter.complete(controller)` above should happen - // in `mapRendered`. - // https://github.com/flutter/flutter/issues/54758 - await Future.delayed(const Duration(seconds: 1)); + await tester.pumpAndSettle(); - final ScreenCoordinate coordinate = - await mapController.getScreenCoordinate(kInitialCameraPosition.target); - final Rect rect = tester.getRect(find.byKey(key)); - if (isIOS || isWeb) { - // On iOS, the coordinate value from the GoogleMapSdk doesn't include the devicePixelRatio`. - // So we don't need to do the conversion like we did below for other platforms. - expect(coordinate.x, (rect.center.dx - rect.topLeft.dx).round()); - expect(coordinate.y, (rect.center.dy - rect.topLeft.dy).round()); - } else { - expect( - coordinate.x, - ((rect.center.dx - rect.topLeft.dx) * tester.view.devicePixelRatio) - .round()); - expect( - coordinate.y, - ((rect.center.dy - rect.topLeft.dy) * tester.view.devicePixelRatio) - .round()); - } - await tester.binding.setSurfaceSize(null); - }, - // Android doesn't like the layout required for the web, so we skip web in this test. - // The equivalent web test already exists here: - // https://github.com/flutter/packages/blob/c43cc13498a1a1c4f3d1b8af2add9ce7c15bd6d0/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/projection_test.dart#L78 - skip: isWeb || - // TODO(stuartmorgan): Re-enable; see https://github.com/flutter/flutter/issues/139825 - isIOS); + // TODO(cyanglaz): Remove this after we added `mapRendered` callback, and `mapControllerCompleter.complete(controller)` above should happen + // in `mapRendered`. + // https://github.com/flutter/flutter/issues/54758 + await Future.delayed(const Duration(seconds: 1)); + + final ScreenCoordinate coordinate = await mapController + .getScreenCoordinate(kInitialCameraPosition.target); + final Rect rect = tester.getRect(find.byKey(key)); + if (isIOS || isWeb) { + // On iOS, the coordinate value from the GoogleMapSdk doesn't include the devicePixelRatio`. + // So we don't need to do the conversion like we did below for other platforms. + expect(coordinate.x, (rect.center.dx - rect.topLeft.dx).round()); + expect(coordinate.y, (rect.center.dy - rect.topLeft.dy).round()); + } else { + expect( + coordinate.x, + ((rect.center.dx - rect.topLeft.dx) * tester.view.devicePixelRatio) + .round()); + expect( + coordinate.y, + ((rect.center.dy - rect.topLeft.dy) * tester.view.devicePixelRatio) + .round()); + } + await tester.binding.setSurfaceSize(null); + }, + // Android doesn't like the layout required for the web, so we skip web in this test. + // The equivalent web test already exists here: + // https://github.com/flutter/packages/blob/c43cc13498a1a1c4f3d1b8af2add9ce7c15bd6d0/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/projection_test.dart#L78 + skip: isWeb || + // TODO(stuartmorgan): Re-enable; see https://github.com/flutter/flutter/issues/139825 + isIOS || + // TODO(tarrinneal): Re-enable; see https://github.com/flutter/flutter/issues/160115 + isAndroid, + ); testWidgets('testGetVisibleRegion', (WidgetTester tester) async { final Key key = GlobalKey(); diff --git a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml index 3326cbae3e5e..0a949e262bbe 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the google_maps_flutter plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: cupertino_icons: ^1.0.5 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md index a42fa3d3076e..b09f2f375b20 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.13.2 * Updates most objects passed from Dart to native to use typed data. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/pubspec.yaml index a130acf4b348..f0a241192822 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the google_maps_flutter plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: cupertino_icons: ^1.0.5 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/pubspec.yaml index a130acf4b348..f0a241192822 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the google_maps_flutter plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: cupertino_icons: ^1.0.5 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/pubspec.yaml index 47faec4a495f..9e6466288a92 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/pubspec.yaml @@ -3,8 +3,8 @@ description: Shared Dart code for the example apps. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: cupertino_icons: ^1.0.5 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml index b90fc561e983..2020ec8940ef 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.13.2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index 49c12ebbbdab..8638e83c6ce3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.9.5 * Converts `BitmapDescriptor` to typesafe structures. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index 67e6a64f1c0f..1ffc34717c91 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.9.5 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: collection: ^1.15.0 diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index 24564442c8f9..eee5a932cf69 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 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 6.2.2 * Adds `missing_code_block_language_in_doc_comment` lint. diff --git a/packages/google_sign_in/google_sign_in/example/macos/Runner/DebugProfile.entitlements b/packages/google_sign_in/google_sign_in/example/macos/Runner/DebugProfile.entitlements index e635cd9a4bf4..dddb8a30c851 100644 --- a/packages/google_sign_in/google_sign_in/example/macos/Runner/DebugProfile.entitlements +++ b/packages/google_sign_in/google_sign_in/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/google_sign_in/google_sign_in/example/macos/Runner/Release.entitlements b/packages/google_sign_in/google_sign_in/example/macos/Runner/Release.entitlements index 0218c441b4e3..852fa1a4728a 100644 --- a/packages/google_sign_in/google_sign_in/example/macos/Runner/Release.entitlements +++ b/packages/google_sign_in/google_sign_in/example/macos/Runner/Release.entitlements @@ -3,7 +3,6 @@ com.apple.security.app-sandbox - - + diff --git a/packages/google_sign_in/google_sign_in/example/pubspec.yaml b/packages/google_sign_in/google_sign_in/example/pubspec.yaml index e4fe3eae18f2..5335068734a8 100644 --- a/packages/google_sign_in/google_sign_in/example/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Example of Google Sign-In plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index c19b4c2b0974..ee1a1e0b61d6 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 6.2.2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md b/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md index d6ab31e98763..f7b0e5617160 100644 --- a/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 5.7.8 * Updates Pigeon for non-nullable collection type support. diff --git a/packages/google_sign_in/google_sign_in_ios/example/macos/Runner/DebugProfile.entitlements b/packages/google_sign_in/google_sign_in_ios/example/macos/Runner/DebugProfile.entitlements index e635cd9a4bf4..dddb8a30c851 100644 --- a/packages/google_sign_in/google_sign_in_ios/example/macos/Runner/DebugProfile.entitlements +++ b/packages/google_sign_in/google_sign_in_ios/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/google_sign_in/google_sign_in_ios/example/macos/Runner/Release.entitlements b/packages/google_sign_in/google_sign_in_ios/example/macos/Runner/Release.entitlements index 0218c441b4e3..852fa1a4728a 100644 --- a/packages/google_sign_in/google_sign_in_ios/example/macos/Runner/Release.entitlements +++ b/packages/google_sign_in/google_sign_in_ios/example/macos/Runner/Release.entitlements @@ -3,7 +3,6 @@ com.apple.security.app-sandbox - - + diff --git a/packages/google_sign_in/google_sign_in_ios/example/pubspec.yaml b/packages/google_sign_in/google_sign_in_ios/example/pubspec.yaml index 7e9558b3d73a..03c1172bde92 100644 --- a/packages/google_sign_in/google_sign_in_ios/example/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_ios/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Example of Google Sign-In plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/google_sign_in/google_sign_in_ios/pubspec.yaml b/packages/google_sign_in/google_sign_in_ios/pubspec.yaml index b4d782f97a98..8b64480c6622 100644 --- a/packages/google_sign_in/google_sign_in_ios/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_ios/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 5.7.8 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: 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 09c84c72eb15..fda470243542 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,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 2.4.5 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 7826912ca88d..2581773c69df 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 @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.4.5 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: 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 7c3db8fd4da4..52e161969d1f 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 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 0.12.4+3 * Fixes callback types for `TokenClientConfig`. diff --git a/packages/google_sign_in/google_sign_in_web/example/pubspec.yaml b/packages/google_sign_in/google_sign_in_web/example/pubspec.yaml index 756f725fe74d..81b6dd8bad3f 100644 --- a/packages/google_sign_in/google_sign_in_web/example/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_web/example/pubspec.yaml @@ -2,8 +2,8 @@ name: google_sign_in_web_integration_tests publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: cupertino_icons: ^1.0.2 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 85aa2ba45a09..ef52f4f3e41c 100644 --- a/packages/google_sign_in/google_sign_in_web/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_web/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.12.4+3 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 29fb408f8b45..ee08d0510f3c 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 1.1.2 * Adds comment for the limit parameter. diff --git a/packages/image_picker/image_picker/example/macos/Runner/DebugProfile.entitlements b/packages/image_picker/image_picker/example/macos/Runner/DebugProfile.entitlements index 04c9acf4af85..0ceee8dff196 100644 --- a/packages/image_picker/image_picker/example/macos/Runner/DebugProfile.entitlements +++ b/packages/image_picker/image_picker/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/image_picker/image_picker/example/macos/Runner/Release.entitlements b/packages/image_picker/image_picker/example/macos/Runner/Release.entitlements index afa43e9be4f6..18aff0ce43c2 100644 --- a/packages/image_picker/image_picker/example/macos/Runner/Release.entitlements +++ b/packages/image_picker/image_picker/example/macos/Runner/Release.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.files.user-selected.read-only diff --git a/packages/image_picker/image_picker/example/pubspec.yaml b/packages/image_picker/image_picker/example/pubspec.yaml index 12e6350a9523..d064fb0f7e87 100644 --- a/packages/image_picker/image_picker/example/pubspec.yaml +++ b/packages/image_picker/image_picker/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the image_picker plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 6c5676a60e0d..d2f49724c883 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.1.2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/image_picker/image_picker_ios/CHANGELOG.md b/packages/image_picker/image_picker_ios/CHANGELOG.md index f31aa5c36662..8fd9f953c285 100644 --- a/packages/image_picker/image_picker_ios/CHANGELOG.md +++ b/packages/image_picker/image_picker_ios/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 0.8.12+1 * Updates Pigeon for non-nullable collection type support. diff --git a/packages/image_picker/image_picker_ios/example/pubspec.yaml b/packages/image_picker/image_picker_ios/example/pubspec.yaml index dbfe54d4420f..bcb238256489 100755 --- a/packages/image_picker/image_picker_ios/example/pubspec.yaml +++ b/packages/image_picker/image_picker_ios/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the image_picker plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/image_picker/image_picker_ios/pubspec.yaml b/packages/image_picker/image_picker_ios/pubspec.yaml index a1f752f33bce..694a7a8cf3bd 100755 --- a/packages/image_picker/image_picker_ios/pubspec.yaml +++ b/packages/image_picker/image_picker_ios/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.8.12+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/image_picker/image_picker_linux/CHANGELOG.md b/packages/image_picker/image_picker_linux/CHANGELOG.md index 50d3dd738917..1fa9bff8eba9 100644 --- a/packages/image_picker/image_picker_linux/CHANGELOG.md +++ b/packages/image_picker/image_picker_linux/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 0.2.1+1 diff --git a/packages/image_picker/image_picker_linux/example/pubspec.yaml b/packages/image_picker/image_picker_linux/example/pubspec.yaml index 5db5fb085f8c..30f2d208a69e 100644 --- a/packages/image_picker/image_picker_linux/example/pubspec.yaml +++ b/packages/image_picker/image_picker_linux/example/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' version: 1.0.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/image_picker/image_picker_linux/pubspec.yaml b/packages/image_picker/image_picker_linux/pubspec.yaml index 8e44fac8d48a..860d59846bf8 100644 --- a/packages/image_picker/image_picker_linux/pubspec.yaml +++ b/packages/image_picker/image_picker_linux/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.2.1+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/image_picker/image_picker_macos/CHANGELOG.md b/packages/image_picker/image_picker_macos/CHANGELOG.md index 6012fff8dbcd..f1b3bd3f1597 100644 --- a/packages/image_picker/image_picker_macos/CHANGELOG.md +++ b/packages/image_picker/image_picker_macos/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 0.2.1+1 diff --git a/packages/image_picker/image_picker_macos/example/pubspec.yaml b/packages/image_picker/image_picker_macos/example/pubspec.yaml index ab0d82bbc305..66435a80756b 100644 --- a/packages/image_picker/image_picker_macos/example/pubspec.yaml +++ b/packages/image_picker/image_picker_macos/example/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' version: 1.0.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/image_picker/image_picker_macos/pubspec.yaml b/packages/image_picker/image_picker_macos/pubspec.yaml index 3b11740e8d86..d5f7181c903a 100644 --- a/packages/image_picker/image_picker_macos/pubspec.yaml +++ b/packages/image_picker/image_picker_macos/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.2.1+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md index 28a9d4b2e1a8..efbec138c57a 100644 --- a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md +++ b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.10.0 * Adds limit parameter to `MediaOptions` and `MultiImagePickerOptions`. diff --git a/packages/image_picker/image_picker_platform_interface/pubspec.yaml b/packages/image_picker/image_picker_platform_interface/pubspec.yaml index 9af992c7c7bf..3f56e0e394d8 100644 --- a/packages/image_picker/image_picker_platform_interface/pubspec.yaml +++ b/packages/image_picker/image_picker_platform_interface/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.10.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: cross_file: ^0.3.1+1 diff --git a/packages/image_picker/image_picker_windows/CHANGELOG.md b/packages/image_picker/image_picker_windows/CHANGELOG.md index 8195bb8a66af..1f41748ce99c 100644 --- a/packages/image_picker/image_picker_windows/CHANGELOG.md +++ b/packages/image_picker/image_picker_windows/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 0.2.1+1 diff --git a/packages/image_picker/image_picker_windows/example/pubspec.yaml b/packages/image_picker/image_picker_windows/example/pubspec.yaml index 744a9e61ba0f..204177a5a9a5 100644 --- a/packages/image_picker/image_picker_windows/example/pubspec.yaml +++ b/packages/image_picker/image_picker_windows/example/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' version: 1.0.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/image_picker/image_picker_windows/pubspec.yaml b/packages/image_picker/image_picker_windows/pubspec.yaml index 51d9a94ee6e4..73e2c59478c0 100644 --- a/packages/image_picker/image_picker_windows/pubspec.yaml +++ b/packages/image_picker/image_picker_windows/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.2.1+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md index d4a2e5ab131d..385b79f69dcf 100644 --- a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 3.2.0 diff --git a/packages/in_app_purchase/in_app_purchase/example/macos/Runner/DebugProfile.entitlements b/packages/in_app_purchase/in_app_purchase/example/macos/Runner/DebugProfile.entitlements index e635cd9a4bf4..dddb8a30c851 100644 --- a/packages/in_app_purchase/in_app_purchase/example/macos/Runner/DebugProfile.entitlements +++ b/packages/in_app_purchase/in_app_purchase/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/in_app_purchase/in_app_purchase/example/macos/Runner/Release.entitlements b/packages/in_app_purchase/in_app_purchase/example/macos/Runner/Release.entitlements index 0218c441b4e3..852fa1a4728a 100644 --- a/packages/in_app_purchase/in_app_purchase/example/macos/Runner/Release.entitlements +++ b/packages/in_app_purchase/in_app_purchase/example/macos/Runner/Release.entitlements @@ -3,7 +3,6 @@ com.apple.security.app-sandbox - - + diff --git a/packages/in_app_purchase/in_app_purchase/example/pubspec.yaml b/packages/in_app_purchase/in_app_purchase/example/pubspec.yaml index c9c79cf63bc4..8423035ea9df 100644 --- a/packages/in_app_purchase/in_app_purchase/example/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the in_app_purchase plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/in_app_purchase/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/in_app_purchase/pubspec.yaml index c5ff3bf3b588..409bfafffcdd 100644 --- a/packages/in_app_purchase/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 3.2.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/in_app_purchase/in_app_purchase_platform_interface/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase_platform_interface/CHANGELOG.md index d8fef6189343..c10788bd48ba 100644 --- a/packages/in_app_purchase/in_app_purchase_platform_interface/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 1.4.0 diff --git a/packages/in_app_purchase/in_app_purchase_platform_interface/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_platform_interface/pubspec.yaml index 9de0b0133408..29760d63412b 100644 --- a/packages/in_app_purchase/in_app_purchase_platform_interface/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase_platform_interface/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.4.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md index 181db40db5e6..225bcc0c1ddb 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 0.3.20+2 * Fixes price not being displayed correctly. diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/DebugProfile.entitlements b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/DebugProfile.entitlements index 25a95d1ac5ca..dddb8a30c851 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/DebugProfile.entitlements +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - < - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/Release.entitlements b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/Release.entitlements index 0218c441b4e3..852fa1a4728a 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/Release.entitlements +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner/Release.entitlements @@ -3,7 +3,6 @@ com.apple.security.app-sandbox - - + diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_storekit/example/pubspec.yaml index a59dafe8df95..40534c1c6c0f 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/example/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase_storekit/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the in_app_purchase_storekit plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml index e7ecbc0ebc1b..dc4444926bb4 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.3.20+2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/ios_platform_images/CHANGELOG.md b/packages/ios_platform_images/CHANGELOG.md index 2dda63366d01..5a1f5490b9e7 100644 --- a/packages/ios_platform_images/CHANGELOG.md +++ b/packages/ios_platform_images/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 0.2.4+1 * Updates to Pigeon v22. diff --git a/packages/ios_platform_images/example/pubspec.yaml b/packages/ios_platform_images/example/pubspec.yaml index 65fa44b71154..612017fbd7b9 100644 --- a/packages/ios_platform_images/example/pubspec.yaml +++ b/packages/ios_platform_images/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the ios_platform_images plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: cupertino_icons: ^1.0.2 diff --git a/packages/ios_platform_images/pubspec.yaml b/packages/ios_platform_images/pubspec.yaml index dc5925b42f7d..2e40b7298aee 100644 --- a/packages/ios_platform_images/pubspec.yaml +++ b/packages/ios_platform_images/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.2.4+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/local_auth/local_auth/CHANGELOG.md b/packages/local_auth/local_auth/CHANGELOG.md index a830dbc1cd6f..262015eb5e91 100644 --- a/packages/local_auth/local_auth/CHANGELOG.md +++ b/packages/local_auth/local_auth/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 2.3.0 diff --git a/packages/local_auth/local_auth/example/pubspec.yaml b/packages/local_auth/local_auth/example/pubspec.yaml index 8bcf50db130d..9b7b87fb44a3 100644 --- a/packages/local_auth/local_auth/example/pubspec.yaml +++ b/packages/local_auth/local_auth/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the local_auth plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/local_auth/local_auth/pubspec.yaml b/packages/local_auth/local_auth/pubspec.yaml index 0ebc00c4d3d4..e81560670869 100644 --- a/packages/local_auth/local_auth/pubspec.yaml +++ b/packages/local_auth/local_auth/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.3.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/local_auth/local_auth_darwin/CHANGELOG.md b/packages/local_auth/local_auth_darwin/CHANGELOG.md index 3caab70bf454..c5fcf90d34a0 100644 --- a/packages/local_auth/local_auth_darwin/CHANGELOG.md +++ b/packages/local_auth/local_auth_darwin/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 1.4.2 * Adds compatibility with `intl` 0.20.0. diff --git a/packages/local_auth/local_auth_darwin/example/pubspec.yaml b/packages/local_auth/local_auth_darwin/example/pubspec.yaml index ab0ca6e62cce..4f204a5b9f82 100644 --- a/packages/local_auth/local_auth_darwin/example/pubspec.yaml +++ b/packages/local_auth/local_auth_darwin/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the local_auth_darwin plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/local_auth/local_auth_darwin/pubspec.yaml b/packages/local_auth/local_auth_darwin/pubspec.yaml index 4ee718f645cf..8aff58fe3698 100644 --- a/packages/local_auth/local_auth_darwin/pubspec.yaml +++ b/packages/local_auth/local_auth_darwin/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.4.2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/local_auth/local_auth_platform_interface/CHANGELOG.md b/packages/local_auth/local_auth_platform_interface/CHANGELOG.md index 30dd66f1c3d1..d0f416c9f277 100644 --- a/packages/local_auth/local_auth_platform_interface/CHANGELOG.md +++ b/packages/local_auth/local_auth_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 1.0.10 diff --git a/packages/local_auth/local_auth_platform_interface/pubspec.yaml b/packages/local_auth/local_auth_platform_interface/pubspec.yaml index 471978598642..62774c28fe68 100644 --- a/packages/local_auth/local_auth_platform_interface/pubspec.yaml +++ b/packages/local_auth/local_auth_platform_interface/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.0.10 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/local_auth/local_auth_windows/CHANGELOG.md b/packages/local_auth/local_auth_windows/CHANGELOG.md index d8654c0a2e79..d9ec70257e69 100644 --- a/packages/local_auth/local_auth_windows/CHANGELOG.md +++ b/packages/local_auth/local_auth_windows/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 1.0.11 diff --git a/packages/local_auth/local_auth_windows/example/pubspec.yaml b/packages/local_auth/local_auth_windows/example/pubspec.yaml index e953214f9853..9bdd40ae5a3c 100644 --- a/packages/local_auth/local_auth_windows/example/pubspec.yaml +++ b/packages/local_auth/local_auth_windows/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the local_auth_windows plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/local_auth/local_auth_windows/pubspec.yaml b/packages/local_auth/local_auth_windows/pubspec.yaml index 1919a989f0c4..8546c20951aa 100644 --- a/packages/local_auth/local_auth_windows/pubspec.yaml +++ b/packages/local_auth/local_auth_windows/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.0.11 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/metrics_center/CHANGELOG.md b/packages/metrics_center/CHANGELOG.md index 904f9775a932..703cfadff97d 100644 --- a/packages/metrics_center/CHANGELOG.md +++ b/packages/metrics_center/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. * Update dependency `http: ^1.0.0` ## 1.0.13 diff --git a/packages/metrics_center/pubspec.yaml b/packages/metrics_center/pubspec.yaml index a1ef1bebcf93..fc89d6ce4125 100644 --- a/packages/metrics_center/pubspec.yaml +++ b/packages/metrics_center/pubspec.yaml @@ -6,7 +6,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/metrics_cente issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+metrics_center%22 environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: _discoveryapis_commons: ^1.0.0 diff --git a/packages/multicast_dns/CHANGELOG.md b/packages/multicast_dns/CHANGELOG.md index b6956e0acbc4..4b23be31ce2d 100644 --- a/packages/multicast_dns/CHANGELOG.md +++ b/packages/multicast_dns/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 0.3.2+7 diff --git a/packages/multicast_dns/pubspec.yaml b/packages/multicast_dns/pubspec.yaml index 8683b680c98a..6f0f3052cc0e 100644 --- a/packages/multicast_dns/pubspec.yaml +++ b/packages/multicast_dns/pubspec.yaml @@ -5,7 +5,7 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.3.2+7 environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: meta: ^1.3.0 diff --git a/packages/palette_generator/CHANGELOG.md b/packages/palette_generator/CHANGELOG.md index 73b2ee0f5a47..a1f7ccf282ab 100644 --- a/packages/palette_generator/CHANGELOG.md +++ b/packages/palette_generator/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 0.3.3+5 * Updates README to link to the published example. diff --git a/packages/palette_generator/example/pubspec.yaml b/packages/palette_generator/example/pubspec.yaml index b0d61af8345c..8f1a28f036bf 100644 --- a/packages/palette_generator/example/pubspec.yaml +++ b/packages/palette_generator/example/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: none version: 0.1.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/palette_generator/pubspec.yaml b/packages/palette_generator/pubspec.yaml index ed67a31c72c9..e43844311d9b 100644 --- a/packages/palette_generator/pubspec.yaml +++ b/packages/palette_generator/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.3.3+5 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: collection: ^1.15.0 diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index 6a8b2aeacd09..1c8d48672e4d 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.1.5 * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. diff --git a/packages/path_provider/path_provider/example/macos/Runner/DebugProfile.entitlements b/packages/path_provider/path_provider/example/macos/Runner/DebugProfile.entitlements index 727d49f3df82..f83e1f42d120 100644 --- a/packages/path_provider/path_provider/example/macos/Runner/DebugProfile.entitlements +++ b/packages/path_provider/path_provider/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/path_provider/path_provider/example/macos/Runner/Release.entitlements b/packages/path_provider/path_provider/example/macos/Runner/Release.entitlements index 8528f1145fe5..9d379927fbcb 100644 --- a/packages/path_provider/path_provider/example/macos/Runner/Release.entitlements +++ b/packages/path_provider/path_provider/example/macos/Runner/Release.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.files.downloads.read-write diff --git a/packages/path_provider/path_provider/example/pubspec.yaml b/packages/path_provider/path_provider/example/pubspec.yaml index 154e969ce49e..0e22c7b18093 100644 --- a/packages/path_provider/path_provider/example/pubspec.yaml +++ b/packages/path_provider/path_provider/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the path_provider plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_foundation/CHANGELOG.md b/packages/path_provider/path_provider_foundation/CHANGELOG.md index 39374d87dcb6..9cd88d4f38ff 100644 --- a/packages/path_provider/path_provider_foundation/CHANGELOG.md +++ b/packages/path_provider/path_provider_foundation/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.4.1 * Updates to Pigeon v22. diff --git a/packages/path_provider/path_provider_foundation/example/macos/Runner/DebugProfile.entitlements b/packages/path_provider/path_provider_foundation/example/macos/Runner/DebugProfile.entitlements index f1461605a918..8139952b3e55 100644 --- a/packages/path_provider/path_provider_foundation/example/macos/Runner/DebugProfile.entitlements +++ b/packages/path_provider/path_provider_foundation/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/path_provider/path_provider_foundation/example/macos/Runner/Release.entitlements b/packages/path_provider/path_provider_foundation/example/macos/Runner/Release.entitlements index bff50d8839cc..2f9659c917fb 100644 --- a/packages/path_provider/path_provider_foundation/example/macos/Runner/Release.entitlements +++ b/packages/path_provider/path_provider_foundation/example/macos/Runner/Release.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.files.downloads.read-write diff --git a/packages/path_provider/path_provider_foundation/example/pubspec.yaml b/packages/path_provider/path_provider_foundation/example/pubspec.yaml index 860c9124c923..559ddef197d9 100644 --- a/packages/path_provider/path_provider_foundation/example/pubspec.yaml +++ b/packages/path_provider/path_provider_foundation/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the path_provider plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_foundation/pubspec.yaml b/packages/path_provider/path_provider_foundation/pubspec.yaml index 02a4dcbdb4af..c274352bfdf0 100644 --- a/packages/path_provider/path_provider_foundation/pubspec.yaml +++ b/packages/path_provider/path_provider_foundation/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.4.1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/path_provider/path_provider_linux/CHANGELOG.md b/packages/path_provider/path_provider_linux/CHANGELOG.md index 68d613ba43a4..b3b8ab37287b 100644 --- a/packages/path_provider/path_provider_linux/CHANGELOG.md +++ b/packages/path_provider/path_provider_linux/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 2.2.1 diff --git a/packages/path_provider/path_provider_linux/example/pubspec.yaml b/packages/path_provider/path_provider_linux/example/pubspec.yaml index 3eb9843ede65..27efc9bbe341 100644 --- a/packages/path_provider/path_provider_linux/example/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the path_provider_linux plugin. publish_to: "none" environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_linux/pubspec.yaml b/packages/path_provider/path_provider_linux/pubspec.yaml index 02e6d6f2bbd7..dd1c058522e7 100644 --- a/packages/path_provider/path_provider_linux/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.2.1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md index 9c60b4e0db93..9754a3ff4deb 100644 --- a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md +++ b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 2.1.2 diff --git a/packages/path_provider/path_provider_platform_interface/pubspec.yaml b/packages/path_provider/path_provider_platform_interface/pubspec.yaml index 2ea8166ed613..0f3d2abad5da 100644 --- a/packages/path_provider/path_provider_platform_interface/pubspec.yaml +++ b/packages/path_provider/path_provider_platform_interface/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.1.2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_windows/CHANGELOG.md b/packages/path_provider/path_provider_windows/CHANGELOG.md index d3c880d9afa7..b165081a4475 100644 --- a/packages/path_provider/path_provider_windows/CHANGELOG.md +++ b/packages/path_provider/path_provider_windows/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 2.3.0 diff --git a/packages/path_provider/path_provider_windows/example/pubspec.yaml b/packages/path_provider/path_provider_windows/example/pubspec.yaml index b5a73980e783..1dafd876e9ee 100644 --- a/packages/path_provider/path_provider_windows/example/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the path_provider plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_windows/pubspec.yaml b/packages/path_provider/path_provider_windows/pubspec.yaml index 8a9d00c42aeb..d507aa329f28 100644 --- a/packages/path_provider/path_provider_windows/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.3.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index f7157e5867c4..e8226fe98562 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 22.7.0 * [swift, kotlin] Adds event channel support. diff --git a/packages/pigeon/example/app/android/app/build.gradle b/packages/pigeon/example/app/android/app/build.gradle index f898ecae685a..e1c8af4f404f 100644 --- a/packages/pigeon/example/app/android/app/build.gradle +++ b/packages/pigeon/example/app/android/app/build.gradle @@ -1,3 +1,9 @@ +plugins { + id "com.android.application" + id "org.jetbrains.kotlin.android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) { } } -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' @@ -21,10 +22,6 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { namespace "dev.flutter.pigeon_example_app" compileSdk flutter.compileSdkVersion @@ -66,7 +63,3 @@ android { flutter { source '../..' } - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/packages/pigeon/example/app/android/build.gradle b/packages/pigeon/example/app/android/build.gradle index 4a9ad584b421..b9db5700753a 100644 --- a/packages/pigeon/example/app/android/build.gradle +++ b/packages/pigeon/example/app/android/build.gradle @@ -1,16 +1,3 @@ -buildscript { - ext.kotlin_version = '1.9.0' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:8.5.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - allprojects { repositories { // See https://github.com/flutter/flutter/blob/master/docs/ecosystem/Plugins-and-Packages-repository-structure.md#gradle-structure for more info. diff --git a/packages/pigeon/example/app/android/settings.gradle b/packages/pigeon/example/app/android/settings.gradle index f246a74091be..29a37a993223 100644 --- a/packages/pigeon/example/app/android/settings.gradle +++ b/packages/pigeon/example/app/android/settings.gradle @@ -1,24 +1,28 @@ -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } - -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" - -// See https://github.com/flutter/flutter/blob/master/docs/ecosystem/Plugins-and-Packages-repository-structure.md#gradle-structure for more info. -buildscript { repositories { - maven { - url "https://plugins.gradle.org/m2/" - } - } - dependencies { - classpath "gradle.plugin.com.google.cloud.artifactregistry:artifactregistry-gradle-plugin:2.2.1" + google() + mavenCentral() + gradlePluginPortal() } } -apply plugin: "com.google.cloud.artifactregistry.gradle-plugin" + +// See https://github.com/flutter/flutter/blob/master/docs/ecosystem/Plugins-and-Packages-repository-structure.md#gradle-structure for more info. +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "8.5.1" apply false + id "org.jetbrains.kotlin.android" version "1.9.0" apply false + id "com.google.cloud.artifactregistry.gradle-plugin" version "2.2.1" + +} + +include ":app" diff --git a/packages/pigeon/example/app/pubspec.yaml b/packages/pigeon/example/app/pubspec.yaml index ab11f4fa8293..afdc8a9ba37a 100644 --- a/packages/pigeon/example/app/pubspec.yaml +++ b/packages/pigeon/example/app/pubspec.yaml @@ -4,7 +4,7 @@ publish_to: 'none' version: 1.0.0 environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: flutter: diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Runner/DebugProfile.entitlements b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Runner/DebugProfile.entitlements index e635cd9a4bf4..dddb8a30c851 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Runner/DebugProfile.entitlements +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Runner/Release.entitlements b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Runner/Release.entitlements index 0218c441b4e3..852fa1a4728a 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Runner/Release.entitlements +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/macos/Runner/Release.entitlements @@ -3,7 +3,6 @@ com.apple.security.app-sandbox - - + diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/pubspec.yaml b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/pubspec.yaml index d40ce1efd995..4839db95cc04 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/pubspec.yaml +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Pigeon test harness for alternate plugin languages. publish_to: 'none' environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: alternate_language_test_plugin: diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/pubspec.yaml b/packages/pigeon/platform_tests/alternate_language_test_plugin/pubspec.yaml index eefdc514fd1e..9e4625dd0378 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/pubspec.yaml +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/pubspec.yaml @@ -4,8 +4,8 @@ version: 0.0.1 publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/pubspec.yaml b/packages/pigeon/platform_tests/shared_test_plugin_code/pubspec.yaml index f0ab70f80712..a345c4c7d304 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/pubspec.yaml +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/pubspec.yaml @@ -4,8 +4,8 @@ version: 0.0.1 publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: build_runner: ^2.1.10 diff --git a/packages/pigeon/platform_tests/test_plugin/example/pubspec.yaml b/packages/pigeon/platform_tests/test_plugin/example/pubspec.yaml index f37ef3a035f0..9b5f46bcb780 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/pubspec.yaml +++ b/packages/pigeon/platform_tests/test_plugin/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Pigeon test harness for primary plugin languages. publish_to: 'none' environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: flutter: diff --git a/packages/pigeon/platform_tests/test_plugin/pubspec.yaml b/packages/pigeon/platform_tests/test_plugin/pubspec.yaml index 2a06f09d03fc..f7a7075da110 100644 --- a/packages/pigeon/platform_tests/test_plugin/pubspec.yaml +++ b/packages/pigeon/platform_tests/test_plugin/pubspec.yaml @@ -4,8 +4,8 @@ version: 0.0.1 publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index a7b5056bac10..d525aba2f223 100644 --- a/packages/pigeon/pubspec.yaml +++ b/packages/pigeon/pubspec.yaml @@ -5,7 +5,7 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 22.7.0 # This must match the version in lib/generator_tools.dart environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: analyzer: ">=5.13.0 <7.0.0" diff --git a/packages/plugin_platform_interface/CHANGELOG.md b/packages/plugin_platform_interface/CHANGELOG.md index 6db60355d829..3b258aa2a0bb 100644 --- a/packages/plugin_platform_interface/CHANGELOG.md +++ b/packages/plugin_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 2.1.8 diff --git a/packages/plugin_platform_interface/pubspec.yaml b/packages/plugin_platform_interface/pubspec.yaml index 2285d41f9173..387a1de6fc0d 100644 --- a/packages/plugin_platform_interface/pubspec.yaml +++ b/packages/plugin_platform_interface/pubspec.yaml @@ -18,7 +18,7 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.1.8 environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: meta: ^1.3.0 diff --git a/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md b/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md index 5affc8fbeff8..bcf1983c780f 100644 --- a/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md +++ b/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 0.10.1+2 diff --git a/packages/pointer_interceptor/pointer_interceptor/example/pubspec.yaml b/packages/pointer_interceptor/pointer_interceptor/example/pubspec.yaml index 1f4e8d771035..e63f87ce5e75 100644 --- a/packages/pointer_interceptor/pointer_interceptor/example/pubspec.yaml +++ b/packages/pointer_interceptor/pointer_interceptor/example/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' version: 1.0.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml b/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml index e7021029913f..16a9325e2ce9 100644 --- a/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml +++ b/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.10.1+2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/pointer_interceptor/pointer_interceptor_ios/CHANGELOG.md b/packages/pointer_interceptor/pointer_interceptor_ios/CHANGELOG.md index 714b5cd05fbc..cfb73d094dd3 100644 --- a/packages/pointer_interceptor/pointer_interceptor_ios/CHANGELOG.md +++ b/packages/pointer_interceptor/pointer_interceptor_ios/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 0.10.1 diff --git a/packages/pointer_interceptor/pointer_interceptor_ios/example/pubspec.yaml b/packages/pointer_interceptor/pointer_interceptor_ios/example/pubspec.yaml index ffbda428f10e..fa15122d1e2e 100644 --- a/packages/pointer_interceptor/pointer_interceptor_ios/example/pubspec.yaml +++ b/packages/pointer_interceptor/pointer_interceptor_ios/example/pubspec.yaml @@ -3,8 +3,8 @@ description: "Demonstrates how to use the pointer_interceptor_ios plugin." publish_to: 'none' environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: cupertino_icons: ^1.0.2 diff --git a/packages/pointer_interceptor/pointer_interceptor_ios/pubspec.yaml b/packages/pointer_interceptor/pointer_interceptor_ios/pubspec.yaml index 194337f8a021..09e124b1a048 100644 --- a/packages/pointer_interceptor/pointer_interceptor_ios/pubspec.yaml +++ b/packages/pointer_interceptor/pointer_interceptor_ios/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.10.1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/pointer_interceptor/pointer_interceptor_platform_interface/CHANGELOG.md b/packages/pointer_interceptor/pointer_interceptor_platform_interface/CHANGELOG.md index 4bafe7e9352d..843fb21366c4 100644 --- a/packages/pointer_interceptor/pointer_interceptor_platform_interface/CHANGELOG.md +++ b/packages/pointer_interceptor/pointer_interceptor_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 0.10.0+1 diff --git a/packages/pointer_interceptor/pointer_interceptor_platform_interface/pubspec.yaml b/packages/pointer_interceptor/pointer_interceptor_platform_interface/pubspec.yaml index 6f5a475c3b63..f778a44d5e22 100644 --- a/packages/pointer_interceptor/pointer_interceptor_platform_interface/pubspec.yaml +++ b/packages/pointer_interceptor/pointer_interceptor_platform_interface/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.10.0+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/process/CHANGELOG.md b/packages/process/CHANGELOG.md index 603c5efc8aec..098292abbb44 100644 --- a/packages/process/CHANGELOG.md +++ b/packages/process/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 5.0.3 * Adds `missing_code_block_language_in_doc_comment` lint. diff --git a/packages/process/pubspec.yaml b/packages/process/pubspec.yaml index 4c5296dc7da8..489272b3d1e7 100644 --- a/packages/process/pubspec.yaml +++ b/packages/process/pubspec.yaml @@ -5,7 +5,7 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 5.0.3 environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: file: '>=6.0.0 <8.0.0' diff --git a/packages/quick_actions/quick_actions/CHANGELOG.md b/packages/quick_actions/quick_actions/CHANGELOG.md index b66476c12e18..c30222dd4da1 100644 --- a/packages/quick_actions/quick_actions/CHANGELOG.md +++ b/packages/quick_actions/quick_actions/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 1.1.0 * Adds localizedSubtitle field for iOS quick actions. diff --git a/packages/quick_actions/quick_actions/example/pubspec.yaml b/packages/quick_actions/quick_actions/example/pubspec.yaml index 7573f5bbf814..1fb3314fdfb1 100644 --- a/packages/quick_actions/quick_actions/example/pubspec.yaml +++ b/packages/quick_actions/quick_actions/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the quick_actions plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/quick_actions/quick_actions/pubspec.yaml b/packages/quick_actions/quick_actions/pubspec.yaml index 98fc3a3bf9f5..a8e9f4e1c245 100644 --- a/packages/quick_actions/quick_actions/pubspec.yaml +++ b/packages/quick_actions/quick_actions/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.1.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/quick_actions/quick_actions_ios/CHANGELOG.md b/packages/quick_actions/quick_actions_ios/CHANGELOG.md index b49fb3602909..c53807404a26 100644 --- a/packages/quick_actions/quick_actions_ios/CHANGELOG.md +++ b/packages/quick_actions/quick_actions_ios/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 1.2.0 * Adds localizedSubtitle field for iOS quick actions. diff --git a/packages/quick_actions/quick_actions_ios/example/pubspec.yaml b/packages/quick_actions/quick_actions_ios/example/pubspec.yaml index d73d5160171b..ead7ff0d0481 100644 --- a/packages/quick_actions/quick_actions_ios/example/pubspec.yaml +++ b/packages/quick_actions/quick_actions_ios/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the quick_actions plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/quick_actions/quick_actions_ios/pubspec.yaml b/packages/quick_actions/quick_actions_ios/pubspec.yaml index a3ba140e2e81..973b5f9cdb5c 100644 --- a/packages/quick_actions/quick_actions_ios/pubspec.yaml +++ b/packages/quick_actions/quick_actions_ios/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.2.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md b/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md index 941bed1ba610..5850f30bedc6 100644 --- a/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md +++ b/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 1.1.0 * Adds localizedSubtitle field for iOS quick actions. diff --git a/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml b/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml index 11ff5823bba1..9635dcb73a1f 100644 --- a/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml +++ b/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.1.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/rfw/CHANGELOG.md b/packages/rfw/CHANGELOG.md index e3fbedffe13d..5fd395e374ed 100644 --- a/packages/rfw/CHANGELOG.md +++ b/packages/rfw/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 1.0.30 * Adds `missing_code_block_language_in_doc_comment` lint. diff --git a/packages/rfw/example/hello/pubspec.yaml b/packages/rfw/example/hello/pubspec.yaml index 54a79fd6effe..398c8041c42f 100644 --- a/packages/rfw/example/hello/pubspec.yaml +++ b/packages/rfw/example/hello/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/rfw/example/local/pubspec.yaml b/packages/rfw/example/local/pubspec.yaml index 7d05f298d00c..5fb34053db8e 100644 --- a/packages/rfw/example/local/pubspec.yaml +++ b/packages/rfw/example/local/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/rfw/example/remote/pubspec.yaml b/packages/rfw/example/remote/pubspec.yaml index 946a8d00ac21..4a2a992f3751 100644 --- a/packages/rfw/example/remote/pubspec.yaml +++ b/packages/rfw/example/remote/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/rfw/example/wasm/pubspec.yaml b/packages/rfw/example/wasm/pubspec.yaml index 04ebcb5402d3..81f2d9549ffe 100644 --- a/packages/rfw/example/wasm/pubspec.yaml +++ b/packages/rfw/example/wasm/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: none # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/rfw/pubspec.yaml b/packages/rfw/pubspec.yaml index 76afa865e101..d152a36c700d 100644 --- a/packages/rfw/pubspec.yaml +++ b/packages/rfw/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.0.30 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/rfw/test_coverage/pubspec.yaml b/packages/rfw/test_coverage/pubspec.yaml index bb29e27c7543..ffee438d8182 100644 --- a/packages/rfw/test_coverage/pubspec.yaml +++ b/packages/rfw/test_coverage/pubspec.yaml @@ -4,7 +4,7 @@ version: 1.0.0 publish_to: none environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: lcov_parser: 0.1.1 diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 81708ac65323..e9275c315abe 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.3.4 + +* Security update, requires shared_preferences_android to be 2.3.4. + ## 2.3.3 * Clarifies scope of prefix handling in README. diff --git a/packages/shared_preferences/shared_preferences/example/macos/Runner/DebugProfile.entitlements b/packages/shared_preferences/shared_preferences/example/macos/Runner/DebugProfile.entitlements index e635cd9a4bf4..dddb8a30c851 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Runner/DebugProfile.entitlements +++ b/packages/shared_preferences/shared_preferences/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/shared_preferences/shared_preferences/example/macos/Runner/Release.entitlements b/packages/shared_preferences/shared_preferences/example/macos/Runner/Release.entitlements index 0218c441b4e3..852fa1a4728a 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Runner/Release.entitlements +++ b/packages/shared_preferences/shared_preferences/example/macos/Runner/Release.entitlements @@ -3,7 +3,6 @@ com.apple.security.app-sandbox - - + diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 6c715ff7e3af..856cd2a22cf4 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -3,11 +3,11 @@ description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.3.3 +version: 2.3.4 environment: - sdk: ^3.4.0 - flutter: ">=3.22.0" + sdk: ^3.5.0 + flutter: ">=3.24.0" flutter: plugin: @@ -28,7 +28,7 @@ flutter: dependencies: flutter: sdk: flutter - shared_preferences_android: ^2.3.0 + shared_preferences_android: ^2.3.4 shared_preferences_foundation: ^2.5.0 shared_preferences_linux: ^2.4.0 shared_preferences_platform_interface: ^2.4.0 diff --git a/packages/shared_preferences/shared_preferences_android/CHANGELOG.md b/packages/shared_preferences/shared_preferences_android/CHANGELOG.md index 958932eda0c3..e8abda3d2628 100644 --- a/packages/shared_preferences/shared_preferences_android/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.4.0 + +* Adds `SharedPreferences` support within `SharedPreferencesAsyncAndroid` API. + ## 2.3.4 * Restrict types when decoding preferences. diff --git a/packages/shared_preferences/shared_preferences_android/README.md b/packages/shared_preferences/shared_preferences_android/README.md index d12b09c068a2..8d8a84e9f135 100644 --- a/packages/shared_preferences/shared_preferences_android/README.md +++ b/packages/shared_preferences/shared_preferences_android/README.md @@ -11,5 +11,22 @@ so you do not need to add it to your `pubspec.yaml`. However, if you `import` this package to use any of its APIs directly, you should add it to your `pubspec.yaml` as usual. +## Options + +The [SharedPreferencesAsync] and [SharedPreferencesWithCache] APIs can use [DataStore Preferences](https://developer.android.com/topic/libraries/architecture/datastore) or [Android SharedPreferences](https://developer.android.com/reference/android/content/SharedPreferences) to store data. + +To use the `Android SharedPreferences` backend, use the `SharedPreferencesAsyncAndroidOptions` when using [SharedPreferencesAsync]. + + +```dart +const SharedPreferencesAsyncAndroidOptions options = + SharedPreferencesAsyncAndroidOptions( + backend: SharedPreferencesAndroidBackendLibrary.SharedPreferences, + originalSharedPreferencesOptions: AndroidSharedPreferencesStoreOptions( + fileName: 'the_name_of_a_file')); +``` + +The [SharedPreferences] API uses the native [Android SharedPreferences](https://developer.android.com/reference/android/content/SharedPreferences) tool to store data. + [1]: https://pub.dev/packages/shared_preferences [2]: https://flutter.dev/to/endorsed-federated-plugin diff --git a/packages/shared_preferences/shared_preferences_android/android/build.gradle b/packages/shared_preferences/shared_preferences_android/android/build.gradle index 28dc9ef31dbe..9d165eaf3e43 100644 --- a/packages/shared_preferences/shared_preferences_android/android/build.gradle +++ b/packages/shared_preferences/shared_preferences_android/android/build.gradle @@ -60,7 +60,8 @@ android { } dependencies { implementation 'androidx.datastore:datastore:1.0.0' - implementation 'androidx.datastore:datastore-preferences:1.0.0' + implementation 'androidx.datastore:datastore-preferences:1.0.0' + implementation 'androidx.preference:preference:1.2.1' testImplementation 'junit:junit:4.13.2' testImplementation 'androidx.test:core-ktx:1.5.0' testImplementation 'androidx.test.ext:junit-ktx:1.2.1' diff --git a/packages/shared_preferences/shared_preferences_android/android/gradle.properties b/packages/shared_preferences/shared_preferences_android/android/gradle.properties new file mode 100644 index 000000000000..598d13fee446 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_android/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx4G +android.useAndroidX=true +android.enableJetifier=true diff --git a/packages/shared_preferences/shared_preferences_android/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MessagesAsync.g.kt b/packages/shared_preferences/shared_preferences_android/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MessagesAsync.g.kt index 159253f4280e..6855bad260b9 100644 --- a/packages/shared_preferences/shared_preferences_android/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MessagesAsync.g.kt +++ b/packages/shared_preferences/shared_preferences_android/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MessagesAsync.g.kt @@ -1,8 +1,9 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v16.0.5), do not edit directly. +// Autogenerated from Pigeon (v22.6.1), do not edit directly. // See also: https://pub.dev/packages/pigeon +@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") package io.flutter.plugins.sharedpreferences @@ -19,10 +20,10 @@ private fun wrapResult(result: Any?): List { } private fun wrapError(exception: Throwable): List { - if (exception is SharedPreferencesError) { - return listOf(exception.code, exception.message, exception.details) + return if (exception is SharedPreferencesError) { + listOf(exception.code, exception.message, exception.details) } else { - return listOf( + listOf( exception.javaClass.simpleName, exception.toString(), "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)) @@ -43,28 +44,27 @@ class SharedPreferencesError( ) : Throwable() /** Generated class from Pigeon that represents data sent in messages. */ -data class SharedPreferencesPigeonOptions(val fileKey: String? = null) { - +data class SharedPreferencesPigeonOptions(val fileName: String? = null, val useDataStore: Boolean) { companion object { - @Suppress("UNCHECKED_CAST") - fun fromList(list: List): SharedPreferencesPigeonOptions { - val fileKey = list[0] as String? - return SharedPreferencesPigeonOptions(fileKey) + fun fromList(pigeonVar_list: List): SharedPreferencesPigeonOptions { + val fileName = pigeonVar_list[0] as String? + val useDataStore = pigeonVar_list[1] as Boolean + return SharedPreferencesPigeonOptions(fileName, useDataStore) } } fun toList(): List { - return listOf( - fileKey, + return listOf( + fileName, + useDataStore, ) } } -@Suppress("UNCHECKED_CAST") -private object SharedPreferencesAsyncApiCodec : StandardMessageCodec() { +private open class MessagesAsyncPigeonCodec : StandardMessageCodec() { override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { return when (type) { - 128.toByte() -> { + 129.toByte() -> { return (readValue(buffer) as? List)?.let { SharedPreferencesPigeonOptions.fromList(it) } @@ -76,7 +76,7 @@ private object SharedPreferencesAsyncApiCodec : StandardMessageCodec() { override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { when (value) { is SharedPreferencesPigeonOptions -> { - stream.write(128) + stream.write(129) writeValue(stream, value.toList()) } else -> super.writeValue(stream, value) @@ -115,19 +115,25 @@ interface SharedPreferencesAsyncApi { companion object { /** The codec used by SharedPreferencesAsyncApi. */ - val codec: MessageCodec by lazy { SharedPreferencesAsyncApiCodec } + val codec: MessageCodec by lazy { MessagesAsyncPigeonCodec() } /** * Sets up an instance of `SharedPreferencesAsyncApi` to handle messages through the * `binaryMessenger`. */ - @Suppress("UNCHECKED_CAST") - fun setUp(binaryMessenger: BinaryMessenger, api: SharedPreferencesAsyncApi?) { + @JvmOverloads + fun setUp( + binaryMessenger: BinaryMessenger, + api: SharedPreferencesAsyncApi?, + messageChannelSuffix: String = "" + ) { + val separatedMessageChannelSuffix = + if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" run { val taskQueue = binaryMessenger.makeBackgroundTaskQueue() val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setBool", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setBool$separatedMessageChannelSuffix", codec, taskQueue) if (api != null) { @@ -136,13 +142,13 @@ interface SharedPreferencesAsyncApi { val keyArg = args[0] as String val valueArg = args[1] as Boolean val optionsArg = args[2] as SharedPreferencesPigeonOptions - var wrapped: List - try { - api.setBool(keyArg, valueArg, optionsArg) - wrapped = listOf(null) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + api.setBool(keyArg, valueArg, optionsArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -154,7 +160,7 @@ interface SharedPreferencesAsyncApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setString", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setString$separatedMessageChannelSuffix", codec, taskQueue) if (api != null) { @@ -163,13 +169,13 @@ interface SharedPreferencesAsyncApi { val keyArg = args[0] as String val valueArg = args[1] as String val optionsArg = args[2] as SharedPreferencesPigeonOptions - var wrapped: List - try { - api.setString(keyArg, valueArg, optionsArg) - wrapped = listOf(null) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + api.setString(keyArg, valueArg, optionsArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -181,22 +187,22 @@ interface SharedPreferencesAsyncApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setInt", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setInt$separatedMessageChannelSuffix", codec, taskQueue) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val keyArg = args[0] as String - val valueArg = args[1].let { if (it is Int) it.toLong() else it as Long } + val valueArg = args[1] as Long val optionsArg = args[2] as SharedPreferencesPigeonOptions - var wrapped: List - try { - api.setInt(keyArg, valueArg, optionsArg) - wrapped = listOf(null) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + api.setInt(keyArg, valueArg, optionsArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -208,7 +214,7 @@ interface SharedPreferencesAsyncApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setDouble", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setDouble$separatedMessageChannelSuffix", codec, taskQueue) if (api != null) { @@ -217,13 +223,13 @@ interface SharedPreferencesAsyncApi { val keyArg = args[0] as String val valueArg = args[1] as Double val optionsArg = args[2] as SharedPreferencesPigeonOptions - var wrapped: List - try { - api.setDouble(keyArg, valueArg, optionsArg) - wrapped = listOf(null) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + api.setDouble(keyArg, valueArg, optionsArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -235,7 +241,7 @@ interface SharedPreferencesAsyncApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setStringList", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setStringList$separatedMessageChannelSuffix", codec, taskQueue) if (api != null) { @@ -244,13 +250,13 @@ interface SharedPreferencesAsyncApi { val keyArg = args[0] as String val valueArg = args[1] as List val optionsArg = args[2] as SharedPreferencesPigeonOptions - var wrapped: List - try { - api.setStringList(keyArg, valueArg, optionsArg) - wrapped = listOf(null) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + api.setStringList(keyArg, valueArg, optionsArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -258,22 +264,24 @@ interface SharedPreferencesAsyncApi { } } run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getString", - codec) + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getString$separatedMessageChannelSuffix", + codec, + taskQueue) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val keyArg = args[0] as String val optionsArg = args[1] as SharedPreferencesPigeonOptions - var wrapped: List - try { - wrapped = listOf(api.getString(keyArg, optionsArg)) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + listOf(api.getString(keyArg, optionsArg)) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -281,22 +289,24 @@ interface SharedPreferencesAsyncApi { } } run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getBool", - codec) + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getBool$separatedMessageChannelSuffix", + codec, + taskQueue) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val keyArg = args[0] as String val optionsArg = args[1] as SharedPreferencesPigeonOptions - var wrapped: List - try { - wrapped = listOf(api.getBool(keyArg, optionsArg)) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + listOf(api.getBool(keyArg, optionsArg)) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -304,22 +314,24 @@ interface SharedPreferencesAsyncApi { } } run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getDouble", - codec) + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getDouble$separatedMessageChannelSuffix", + codec, + taskQueue) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val keyArg = args[0] as String val optionsArg = args[1] as SharedPreferencesPigeonOptions - var wrapped: List - try { - wrapped = listOf(api.getDouble(keyArg, optionsArg)) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + listOf(api.getDouble(keyArg, optionsArg)) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -327,22 +339,24 @@ interface SharedPreferencesAsyncApi { } } run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getInt", - codec) + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getInt$separatedMessageChannelSuffix", + codec, + taskQueue) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val keyArg = args[0] as String val optionsArg = args[1] as SharedPreferencesPigeonOptions - var wrapped: List - try { - wrapped = listOf(api.getInt(keyArg, optionsArg)) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + listOf(api.getInt(keyArg, optionsArg)) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -350,22 +364,24 @@ interface SharedPreferencesAsyncApi { } } run { + val taskQueue = binaryMessenger.makeBackgroundTaskQueue() val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getStringList", - codec) + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getStringList$separatedMessageChannelSuffix", + codec, + taskQueue) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val keyArg = args[0] as String val optionsArg = args[1] as SharedPreferencesPigeonOptions - var wrapped: List - try { - wrapped = listOf(api.getStringList(keyArg, optionsArg)) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + listOf(api.getStringList(keyArg, optionsArg)) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -377,7 +393,7 @@ interface SharedPreferencesAsyncApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.clear", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.clear$separatedMessageChannelSuffix", codec, taskQueue) if (api != null) { @@ -385,13 +401,13 @@ interface SharedPreferencesAsyncApi { val args = message as List val allowListArg = args[0] as List? val optionsArg = args[1] as SharedPreferencesPigeonOptions - var wrapped: List - try { - api.clear(allowListArg, optionsArg) - wrapped = listOf(null) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + api.clear(allowListArg, optionsArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -403,7 +419,7 @@ interface SharedPreferencesAsyncApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getAll", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getAll$separatedMessageChannelSuffix", codec, taskQueue) if (api != null) { @@ -411,12 +427,12 @@ interface SharedPreferencesAsyncApi { val args = message as List val allowListArg = args[0] as List? val optionsArg = args[1] as SharedPreferencesPigeonOptions - var wrapped: List - try { - wrapped = listOf(api.getAll(allowListArg, optionsArg)) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + listOf(api.getAll(allowListArg, optionsArg)) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { @@ -428,7 +444,7 @@ interface SharedPreferencesAsyncApi { val channel = BasicMessageChannel( binaryMessenger, - "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getKeys", + "dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getKeys$separatedMessageChannelSuffix", codec, taskQueue) if (api != null) { @@ -436,12 +452,12 @@ interface SharedPreferencesAsyncApi { val args = message as List val allowListArg = args[0] as List? val optionsArg = args[1] as SharedPreferencesPigeonOptions - var wrapped: List - try { - wrapped = listOf(api.getKeys(allowListArg, optionsArg)) - } catch (exception: Throwable) { - wrapped = wrapError(exception) - } + val wrapped: List = + try { + listOf(api.getKeys(allowListArg, optionsArg)) + } catch (exception: Throwable) { + wrapError(exception) + } reply.reply(wrapped) } } else { diff --git a/packages/shared_preferences/shared_preferences_android/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.kt b/packages/shared_preferences/shared_preferences_android/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.kt index 84c38630b899..e0ca35b258cf 100644 --- a/packages/shared_preferences/shared_preferences_android/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.kt +++ b/packages/shared_preferences/shared_preferences_android/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.kt @@ -5,6 +5,7 @@ package io.flutter.plugins.sharedpreferences import android.content.Context +import android.content.SharedPreferences import android.util.Base64 import android.util.Log import androidx.annotation.VisibleForTesting @@ -16,6 +17,7 @@ import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.longPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore +import androidx.preference.PreferenceManager import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.plugin.common.BinaryMessenger import java.io.ByteArrayInputStream @@ -29,6 +31,7 @@ import kotlinx.coroutines.runBlocking const val TAG = "SharedPreferencesPlugin" const val SHARED_PREFERENCES_NAME = "FlutterSharedPreferences" const val LIST_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu" +const val DOUBLE_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBEb3VibGUu" private val Context.sharedPreferencesDataStore: DataStore by preferencesDataStore(SHARED_PREFERENCES_NAME) @@ -36,6 +39,7 @@ private val Context.sharedPreferencesDataStore: DataStore by /// SharedPreferencesPlugin class SharedPreferencesPlugin() : FlutterPlugin, SharedPreferencesAsyncApi { private lateinit var context: Context + private var backend: SharedPreferencesBackend? = null private var listEncoder = ListEncoder() as SharedPreferencesListEncoder @@ -47,7 +51,8 @@ class SharedPreferencesPlugin() : FlutterPlugin, SharedPreferencesAsyncApi { private fun setUp(messenger: BinaryMessenger, context: Context) { this.context = context try { - SharedPreferencesAsyncApi.setUp(messenger, this) + SharedPreferencesAsyncApi.setUp(messenger, this, "data_store") + backend = SharedPreferencesBackend(messenger, context, listEncoder) } catch (ex: Exception) { Log.e(TAG, "Received exception while setting up SharedPreferencesPlugin", ex) } @@ -59,7 +64,9 @@ class SharedPreferencesPlugin() : FlutterPlugin, SharedPreferencesAsyncApi { } override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { - SharedPreferencesAsyncApi.setUp(binding.binaryMessenger, null) + SharedPreferencesAsyncApi.setUp(binding.binaryMessenger, null, "data_store") + backend?.tearDown() + backend = null } /** Adds property to data store of type bool. */ @@ -135,7 +142,6 @@ class SharedPreferencesPlugin() : FlutterPlugin, SharedPreferencesAsyncApi { val preferencesKey = longPreferencesKey(key) val preferenceFlow: Flow = context.sharedPreferencesDataStore.data.map { preferences -> preferences[preferencesKey] } - value = preferenceFlow.firstOrNull() } return value @@ -144,6 +150,7 @@ class SharedPreferencesPlugin() : FlutterPlugin, SharedPreferencesAsyncApi { /** Gets bool at [key] from data store. */ override fun getBool(key: String, options: SharedPreferencesPigeonOptions): Boolean? { val value: Boolean? + runBlocking { val preferencesKey = booleanPreferencesKey(key) val preferenceFlow: Flow = @@ -160,7 +167,7 @@ class SharedPreferencesPlugin() : FlutterPlugin, SharedPreferencesAsyncApi { val preferencesKey = stringPreferencesKey(key) val preferenceFlow: Flow = context.sharedPreferencesDataStore.data.map { preferences -> - transformPref(preferences[preferencesKey] as Any?) as Double? + transformPref(preferences[preferencesKey] as Any?, listEncoder) as Double? } value = preferenceFlow.firstOrNull() @@ -183,7 +190,8 @@ class SharedPreferencesPlugin() : FlutterPlugin, SharedPreferencesAsyncApi { /** Gets StringList at [key] from data store. */ override fun getStringList(key: String, options: SharedPreferencesPigeonOptions): List? { - return (transformPref(getString(key, options) as Any?) as List<*>?)?.filterIsInstance() + val value: List<*>? = transformPref(getString(key, options) as Any?, listEncoder) as List<*>? + return value?.filterIsInstance() } /** Gets all properties from data store. */ @@ -200,10 +208,10 @@ class SharedPreferencesPlugin() : FlutterPlugin, SharedPreferencesAsyncApi { val filteredMap = mutableMapOf() val keys = readAllKeys() - keys?.forEach() { key -> + keys?.forEach { key -> val value = getValueByKey(key) if (preferencesFilter(key.toString(), value, allowSet)) { - val transformedValue = transformPref(value) + val transformedValue = transformPref(value, listEncoder) if (transformedValue != null) { filteredMap[key.toString()] = transformedValue } @@ -221,45 +229,199 @@ class SharedPreferencesPlugin() : FlutterPlugin, SharedPreferencesAsyncApi { val value = context.sharedPreferencesDataStore.data.map { it[key] } return value.firstOrNull() } +} + +class SharedPreferencesBackend( + private var messenger: BinaryMessenger, + private var context: Context, + private var listEncoder: SharedPreferencesListEncoder = ListEncoder() +) : SharedPreferencesAsyncApi { + + init { + try { + SharedPreferencesAsyncApi.setUp(messenger, this, "shared_preferences") + } catch (ex: Exception) { + Log.e(TAG, "Received exception while setting up SharedPreferencesBackend", ex) + } + } + + fun tearDown() { + SharedPreferencesAsyncApi.setUp(messenger, null, "shared_preferences") + } - /** - * Returns false for any preferences that are not included in [allowList]. - * - * If no [allowList] is provided, instead returns false for any preferences that are not supported - * by shared_preferences. - */ - private fun preferencesFilter(key: String, value: Any?, allowList: Set?): Boolean { - if (allowList == null) { - return value is Boolean || value is Long || value is String || value is Double + private fun createSharedPreferences(options: SharedPreferencesPigeonOptions): SharedPreferences { + return if (options.fileName == null) { + PreferenceManager.getDefaultSharedPreferences(context) + } else { + context.getSharedPreferences(options.fileName, Context.MODE_PRIVATE) } + } + + /** Adds property to data store of type bool. */ + override fun setBool(key: String, value: Boolean, options: SharedPreferencesPigeonOptions) { + return createSharedPreferences(options).edit().putBoolean(key, value).apply() + } + + /** Adds property to data store of type String. */ + override fun setString(key: String, value: String, options: SharedPreferencesPigeonOptions) { + return createSharedPreferences(options).edit().putString(key, value).apply() + } + + /** Adds property to data store of type int. Converted to Long by pigeon, and saved as such. */ + override fun setInt(key: String, value: Long, options: SharedPreferencesPigeonOptions) { + return createSharedPreferences(options).edit().putLong(key, value).apply() + } + + /** Adds property to data store of type double. */ + override fun setDouble(key: String, value: Double, options: SharedPreferencesPigeonOptions) { + return createSharedPreferences(options).edit().putString(key, DOUBLE_PREFIX + value).apply() + } - return allowList.contains(key) + /** Adds property to data store of type List. */ + override fun setStringList( + key: String, + value: List, + options: SharedPreferencesPigeonOptions + ) { + val valueString = LIST_PREFIX + listEncoder.encode(value) + return createSharedPreferences(options).edit().putString(key, valueString).apply() } - /** Transforms preferences that are stored as Strings back to original type. */ - private fun transformPref(value: Any?): Any? { - if (value is String) { - if (value.startsWith(LIST_PREFIX)) { - return listEncoder.decode(value.substring(LIST_PREFIX.length)) + /** Removes all properties from data store. */ + override fun clear(allowList: List?, options: SharedPreferencesPigeonOptions) { + val preferences = createSharedPreferences(options) + val clearEditor: SharedPreferences.Editor = preferences.edit() + val allPrefs: Map = preferences.all + val filteredPrefs = ArrayList() + for (key in allPrefs.keys) { + if (preferencesFilter(key, allPrefs[key], allowList = allowList?.toSet())) { + filteredPrefs.add(key) } } - return value + for (key in filteredPrefs) { + clearEditor.remove(key) + } + return clearEditor.apply() } - /** Class that provides tools for encoding and decoding List to String and back. */ - class ListEncoder : SharedPreferencesListEncoder { - override fun encode(list: List): String { - val byteStream = ByteArrayOutputStream() - val stream = ObjectOutputStream(byteStream) - stream.writeObject(list) - stream.flush() - return Base64.encodeToString(byteStream.toByteArray(), 0) + /** Gets all properties from data store. */ + override fun getAll( + allowList: List?, + options: SharedPreferencesPigeonOptions + ): Map { + val preferences = createSharedPreferences(options) + val allPrefs: Map = preferences.all + val filteredPrefs = HashMap() + for (entry in allPrefs.entries) { + if (preferencesFilter(entry.key, entry.value, allowList = allowList?.toSet())) { + entry.value?.let { filteredPrefs.put(entry.key, transformPref(it, listEncoder) as Any) } + } + } + return filteredPrefs + } + + /** Gets int (as long) at [key] from data store. */ + override fun getInt(key: String, options: SharedPreferencesPigeonOptions): Long? { + val preferences = createSharedPreferences(options) + return if (preferences.contains(key)) { + preferences.getLong(key, 0) + } else { + null + } + } + + /** Gets bool at [key] from data store. */ + override fun getBool(key: String, options: SharedPreferencesPigeonOptions): Boolean? { + val preferences = createSharedPreferences(options) + return if (preferences.contains(key)) { + preferences.getBoolean(key, true) + } else { + null } + } + /** Gets double at [key] from data store. */ + override fun getDouble(key: String, options: SharedPreferencesPigeonOptions): Double? { + val preferences = createSharedPreferences(options) + return if (preferences.contains(key)) { + transformPref(preferences.getString(key, ""), listEncoder) as Double + } else { + null + } + } - override fun decode(listString: String): List { - val byteArray = Base64.decode(listString, 0) - val stream = StringListObjectInputStream(ByteArrayInputStream(byteArray)) - return (stream.readObject() as List<*>).filterIsInstance() + /** Gets String at [key] from data store. */ + override fun getString(key: String, options: SharedPreferencesPigeonOptions): String? { + val preferences = createSharedPreferences(options) + return if (preferences.contains(key)) { + preferences.getString(key, "") + } else { + null } } + + /** Gets StringList at [key] from data store. */ + override fun getStringList(key: String, options: SharedPreferencesPigeonOptions): List? { + val preferences = createSharedPreferences(options) + return if (preferences.contains(key)) { + (transformPref(preferences.getString(key, ""), listEncoder) as List<*>?)?.filterIsInstance< + String>() + } else { + null + } + } + + /** Gets all properties from data store. */ + override fun getKeys( + allowList: List?, + options: SharedPreferencesPigeonOptions + ): List { + val preferences = createSharedPreferences(options) + return preferences.all + .filter { preferencesFilter(it.key, it.value, allowList?.toSet()) } + .keys + .toList() + } +} + +/** + * Returns false for any preferences that are not included in [allowList]. + * + * If no [allowList] is provided, instead returns false for any preferences that are not supported + * by shared_preferences. + */ +internal fun preferencesFilter(key: String, value: Any?, allowList: Set?): Boolean { + if (allowList == null) { + return value is Boolean || value is Long || value is String || value is Double + } + + return allowList.contains(key) +} + +/** Transforms preferences that are stored as Strings back to original type. */ +internal fun transformPref(value: Any?, listEncoder: SharedPreferencesListEncoder): Any? { + if (value is String) { + if (value.startsWith(LIST_PREFIX)) { + return listEncoder.decode(value.substring(LIST_PREFIX.length)) + } else if (value.startsWith(DOUBLE_PREFIX)) { + return value.substring(DOUBLE_PREFIX.length).toDouble() + } + } + return value +} + +/** Class that provides tools for encoding and decoding List to String and back. */ +class ListEncoder : SharedPreferencesListEncoder { + override fun encode(list: List): String { + val byteStream = ByteArrayOutputStream() + val stream = ObjectOutputStream(byteStream) + stream.writeObject(list) + stream.flush() + return Base64.encodeToString(byteStream.toByteArray(), 0) + } + + override fun decode(listString: String): List { + val byteArray = Base64.decode(listString, 0) + val stream = StringListObjectInputStream(ByteArrayInputStream(byteArray)) + return (stream.readObject() as List<*>).filterIsInstance() + } } diff --git a/packages/shared_preferences/shared_preferences_android/android/src/test/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesTest.kt b/packages/shared_preferences/shared_preferences_android/android/src/test/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesTest.kt index ad5d6420ccec..1803138bc123 100644 --- a/packages/shared_preferences/shared_preferences_android/android/src/test/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesTest.kt +++ b/packages/shared_preferences/shared_preferences_android/android/src/test/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesTest.kt @@ -5,7 +5,9 @@ package io.flutter.plugins.sharedpreferences import android.content.Context +import android.content.SharedPreferences import android.util.Base64 +import androidx.preference.PreferenceManager import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.flutter.embedding.engine.plugins.FlutterPlugin @@ -41,98 +43,104 @@ internal class SharedPreferencesTest { private val testList = listOf("foo", "bar") - private val emptyOptions = SharedPreferencesPigeonOptions() - - private fun pluginSetup(): SharedPreferencesPlugin { - val testContext: Context = ApplicationProvider.getApplicationContext() + private val dataStoreOptions = SharedPreferencesPigeonOptions(useDataStore = true) + private val sharedPreferencesOptions = SharedPreferencesPigeonOptions(useDataStore = false) + private val testContext: Context = ApplicationProvider.getApplicationContext() + private fun pluginSetup(options: SharedPreferencesPigeonOptions): SharedPreferencesAsyncApi { val plugin = SharedPreferencesPlugin() val binaryMessenger = mockk() val flutterPluginBinding = mockk() every { flutterPluginBinding.binaryMessenger } returns binaryMessenger every { flutterPluginBinding.applicationContext } returns testContext plugin.onAttachedToEngine(flutterPluginBinding) - plugin.clear(null, emptyOptions) - return plugin + val backend = + SharedPreferencesBackend( + flutterPluginBinding.binaryMessenger, flutterPluginBinding.applicationContext) + return if (options.useDataStore) { + plugin + } else { + backend + } } @Test - fun testSetAndGetBool() { - val plugin = pluginSetup() - plugin.setBool(boolKey, testBool, emptyOptions) - Assert.assertEquals(plugin.getBool(boolKey, emptyOptions), testBool) + fun testSetAndGetBoolWithDataStore() { + val plugin = pluginSetup(dataStoreOptions) + plugin.setBool(boolKey, testBool, dataStoreOptions) + Assert.assertEquals(plugin.getBool(boolKey, dataStoreOptions), testBool) } @Test - fun testSetAndGetString() { - val plugin = pluginSetup() - plugin.setString(stringKey, testString, emptyOptions) - Assert.assertEquals(plugin.getString(stringKey, emptyOptions), testString) + fun testSetAndGetStringWithDataStore() { + val plugin = pluginSetup(dataStoreOptions) + plugin.setString(stringKey, testString, dataStoreOptions) + Assert.assertEquals(plugin.getString(stringKey, dataStoreOptions), testString) } @Test - fun testSetAndGetInt() { - val plugin = pluginSetup() - plugin.setInt(intKey, testInt, emptyOptions) - Assert.assertEquals(plugin.getInt(intKey, emptyOptions), testInt) + fun testSetAndGetIntWithDataStore() { + val plugin = pluginSetup(dataStoreOptions) + plugin.setInt(intKey, testInt, dataStoreOptions) + Assert.assertEquals(plugin.getInt(intKey, dataStoreOptions), testInt) } @Test - fun testSetAndGetDouble() { - val plugin = pluginSetup() - plugin.setDouble(doubleKey, testDouble, emptyOptions) - Assert.assertEquals(plugin.getDouble(doubleKey, emptyOptions), testDouble) + fun testSetAndGetDoubleWithDataStore() { + val plugin = pluginSetup(dataStoreOptions) + plugin.setDouble(doubleKey, testDouble, dataStoreOptions) + Assert.assertEquals(plugin.getDouble(doubleKey, dataStoreOptions), testDouble) } @Test - fun testSetAndGetStringList() { - val plugin = pluginSetup() - plugin.setStringList(listKey, testList, emptyOptions) - Assert.assertEquals(plugin.getStringList(listKey, emptyOptions), testList) + fun testSetAndGetStringListWithDataStore() { + val plugin = pluginSetup(dataStoreOptions) + plugin.setStringList(listKey, testList, dataStoreOptions) + Assert.assertEquals(plugin.getStringList(listKey, dataStoreOptions), testList) } @Test - fun testGetKeys() { - val plugin = pluginSetup() - plugin.setBool(boolKey, testBool, emptyOptions) - plugin.setString(stringKey, testString, emptyOptions) - plugin.setInt(intKey, testInt, emptyOptions) - plugin.setDouble(doubleKey, testDouble, emptyOptions) - plugin.setStringList(listKey, testList, emptyOptions) - val keyList = plugin.getKeys(listOf(boolKey, stringKey), emptyOptions) + fun testGetKeysWithDataStore() { + val plugin = pluginSetup(dataStoreOptions) + plugin.setBool(boolKey, testBool, dataStoreOptions) + plugin.setString(stringKey, testString, dataStoreOptions) + plugin.setInt(intKey, testInt, dataStoreOptions) + plugin.setDouble(doubleKey, testDouble, dataStoreOptions) + plugin.setStringList(listKey, testList, dataStoreOptions) + val keyList = plugin.getKeys(listOf(boolKey, stringKey), dataStoreOptions) Assert.assertEquals(keyList.size, 2) Assert.assertTrue(keyList.contains(stringKey)) Assert.assertTrue(keyList.contains(boolKey)) } @Test - fun testClear() { - val plugin = pluginSetup() - plugin.setBool(boolKey, testBool, emptyOptions) - plugin.setString(stringKey, testString, emptyOptions) - plugin.setInt(intKey, testInt, emptyOptions) - plugin.setDouble(doubleKey, testDouble, emptyOptions) - plugin.setStringList(listKey, testList, emptyOptions) - - plugin.clear(null, emptyOptions) - - Assert.assertNull(plugin.getBool(boolKey, emptyOptions)) - Assert.assertNull(plugin.getBool(stringKey, emptyOptions)) - Assert.assertNull(plugin.getBool(intKey, emptyOptions)) - Assert.assertNull(plugin.getBool(doubleKey, emptyOptions)) - Assert.assertNull(plugin.getBool(listKey, emptyOptions)) + fun testClearWithDataStore() { + val plugin = pluginSetup(dataStoreOptions) + plugin.setBool(boolKey, testBool, dataStoreOptions) + plugin.setString(stringKey, testString, dataStoreOptions) + plugin.setInt(intKey, testInt, dataStoreOptions) + plugin.setDouble(doubleKey, testDouble, dataStoreOptions) + plugin.setStringList(listKey, testList, dataStoreOptions) + + plugin.clear(null, dataStoreOptions) + + Assert.assertNull(plugin.getBool(boolKey, dataStoreOptions)) + Assert.assertNull(plugin.getBool(stringKey, dataStoreOptions)) + Assert.assertNull(plugin.getBool(intKey, dataStoreOptions)) + Assert.assertNull(plugin.getBool(doubleKey, dataStoreOptions)) + Assert.assertNull(plugin.getBool(listKey, dataStoreOptions)) } @Test - fun testGetAll() { - val plugin = pluginSetup() - plugin.setBool(boolKey, testBool, emptyOptions) - plugin.setString(stringKey, testString, emptyOptions) - plugin.setInt(intKey, testInt, emptyOptions) - plugin.setDouble(doubleKey, testDouble, emptyOptions) - plugin.setStringList(listKey, testList, emptyOptions) + fun testGetAllWithDataStore() { + val plugin = pluginSetup(dataStoreOptions) + plugin.setBool(boolKey, testBool, dataStoreOptions) + plugin.setString(stringKey, testString, dataStoreOptions) + plugin.setInt(intKey, testInt, dataStoreOptions) + plugin.setDouble(doubleKey, testDouble, dataStoreOptions) + plugin.setStringList(listKey, testList, dataStoreOptions) - val all = plugin.getAll(null, emptyOptions) + val all = plugin.getAll(null, dataStoreOptions) Assert.assertEquals(all[boolKey], testBool) Assert.assertEquals(all[stringKey], testString) @@ -142,33 +150,154 @@ internal class SharedPreferencesTest { } @Test - fun testClearWithAllowList() { - val plugin = pluginSetup() - plugin.setBool(boolKey, testBool, emptyOptions) - plugin.setString(stringKey, testString, emptyOptions) - plugin.setInt(intKey, testInt, emptyOptions) - plugin.setDouble(doubleKey, testDouble, emptyOptions) - plugin.setStringList(listKey, testList, emptyOptions) + fun testClearWithAllowListWithDataStore() { + val plugin = pluginSetup(dataStoreOptions) + plugin.setBool(boolKey, testBool, dataStoreOptions) + plugin.setString(stringKey, testString, dataStoreOptions) + plugin.setInt(intKey, testInt, dataStoreOptions) + plugin.setDouble(doubleKey, testDouble, dataStoreOptions) + plugin.setStringList(listKey, testList, dataStoreOptions) + + plugin.clear(listOf(boolKey, stringKey), dataStoreOptions) + + Assert.assertNull(plugin.getBool(boolKey, dataStoreOptions)) + Assert.assertNull(plugin.getString(stringKey, dataStoreOptions)) + Assert.assertNotNull(plugin.getInt(intKey, dataStoreOptions)) + Assert.assertNotNull(plugin.getDouble(doubleKey, dataStoreOptions)) + Assert.assertNotNull(plugin.getStringList(listKey, dataStoreOptions)) + } + + @Test + fun testGetAllWithAllowListWithDataStore() { + val plugin = pluginSetup(dataStoreOptions) + plugin.setBool(boolKey, testBool, dataStoreOptions) + plugin.setString(stringKey, testString, dataStoreOptions) + plugin.setInt(intKey, testInt, dataStoreOptions) + plugin.setDouble(doubleKey, testDouble, dataStoreOptions) + plugin.setStringList(listKey, testList, dataStoreOptions) + + val all = plugin.getAll(listOf(boolKey, stringKey), dataStoreOptions) + + Assert.assertEquals(all[boolKey], testBool) + Assert.assertEquals(all[stringKey], testString) + Assert.assertNull(all[intKey]) + Assert.assertNull(all[doubleKey]) + Assert.assertNull(all[listKey]) + } + + @Test + fun testSetAndGetBoolWithSharedPreferences() { + val plugin = pluginSetup(sharedPreferencesOptions) + plugin.setBool(boolKey, testBool, sharedPreferencesOptions) + Assert.assertEquals(plugin.getBool(boolKey, sharedPreferencesOptions), testBool) + } - plugin.clear(listOf(boolKey, stringKey), emptyOptions) + @Test + fun testSetAndGetStringWithSharedPreferences() { + val plugin = pluginSetup(sharedPreferencesOptions) + plugin.setString(stringKey, testString, sharedPreferencesOptions) + Assert.assertEquals(plugin.getString(stringKey, sharedPreferencesOptions), testString) + } - Assert.assertNull(plugin.getBool(boolKey, emptyOptions)) - Assert.assertNull(plugin.getString(stringKey, emptyOptions)) - Assert.assertNotNull(plugin.getInt(intKey, emptyOptions)) - Assert.assertNotNull(plugin.getDouble(doubleKey, emptyOptions)) - Assert.assertNotNull(plugin.getStringList(listKey, emptyOptions)) + @Test + fun testSetAndGetIntWithSharedPreferences() { + val plugin = pluginSetup(sharedPreferencesOptions) + plugin.setInt(intKey, testInt, sharedPreferencesOptions) + Assert.assertEquals(plugin.getInt(intKey, sharedPreferencesOptions), testInt) } @Test - fun testGetAllWithAllowList() { - val plugin = pluginSetup() - plugin.setBool(boolKey, testBool, emptyOptions) - plugin.setString(stringKey, testString, emptyOptions) - plugin.setInt(intKey, testInt, emptyOptions) - plugin.setDouble(doubleKey, testDouble, emptyOptions) - plugin.setStringList(listKey, testList, emptyOptions) + fun testSetAndGetDoubleWithSharedPreferences() { + val plugin = pluginSetup(sharedPreferencesOptions) + plugin.setDouble(doubleKey, testDouble, sharedPreferencesOptions) + Assert.assertEquals(plugin.getDouble(doubleKey, sharedPreferencesOptions), testDouble) + } - val all = plugin.getAll(listOf(boolKey, stringKey), emptyOptions) + @Test + fun testSetAndGetStringListWithSharedPreferences() { + val plugin = pluginSetup(sharedPreferencesOptions) + plugin.setStringList(listKey, testList, sharedPreferencesOptions) + Assert.assertEquals(plugin.getStringList(listKey, sharedPreferencesOptions), testList) + } + + @Test + fun testGetKeysWithSharedPreferences() { + val plugin = pluginSetup(sharedPreferencesOptions) + plugin.setBool(boolKey, testBool, sharedPreferencesOptions) + plugin.setString(stringKey, testString, sharedPreferencesOptions) + plugin.setInt(intKey, testInt, sharedPreferencesOptions) + plugin.setDouble(doubleKey, testDouble, sharedPreferencesOptions) + plugin.setStringList(listKey, testList, sharedPreferencesOptions) + val keyList = plugin.getKeys(listOf(boolKey, stringKey), sharedPreferencesOptions) + Assert.assertEquals(keyList.size, 2) + Assert.assertTrue(keyList.contains(stringKey)) + Assert.assertTrue(keyList.contains(boolKey)) + } + + @Test + fun testClearWithSharedPreferences() { + val plugin = pluginSetup(sharedPreferencesOptions) + plugin.setBool(boolKey, testBool, sharedPreferencesOptions) + plugin.setString(stringKey, testString, sharedPreferencesOptions) + plugin.setInt(intKey, testInt, sharedPreferencesOptions) + plugin.setDouble(doubleKey, testDouble, sharedPreferencesOptions) + plugin.setStringList(listKey, testList, sharedPreferencesOptions) + + plugin.clear(null, sharedPreferencesOptions) + + Assert.assertNull(plugin.getBool(boolKey, sharedPreferencesOptions)) + Assert.assertNull(plugin.getBool(stringKey, sharedPreferencesOptions)) + Assert.assertNull(plugin.getBool(intKey, sharedPreferencesOptions)) + Assert.assertNull(plugin.getBool(doubleKey, sharedPreferencesOptions)) + Assert.assertNull(plugin.getBool(listKey, sharedPreferencesOptions)) + } + + @Test + fun testGetAllWithSharedPreferences() { + val plugin = pluginSetup(sharedPreferencesOptions) + plugin.setBool(boolKey, testBool, sharedPreferencesOptions) + plugin.setString(stringKey, testString, sharedPreferencesOptions) + plugin.setInt(intKey, testInt, sharedPreferencesOptions) + plugin.setDouble(doubleKey, testDouble, sharedPreferencesOptions) + plugin.setStringList(listKey, testList, sharedPreferencesOptions) + + val all = plugin.getAll(null, sharedPreferencesOptions) + + Assert.assertEquals(all[boolKey], testBool) + Assert.assertEquals(all[stringKey], testString) + Assert.assertEquals(all[intKey], testInt) + Assert.assertEquals(all[doubleKey], testDouble) + Assert.assertEquals(all[listKey], testList) + } + + @Test + fun testClearWithAllowListWithSharedPreferences() { + val plugin = pluginSetup(sharedPreferencesOptions) + plugin.setBool(boolKey, testBool, sharedPreferencesOptions) + plugin.setString(stringKey, testString, sharedPreferencesOptions) + plugin.setInt(intKey, testInt, sharedPreferencesOptions) + plugin.setDouble(doubleKey, testDouble, sharedPreferencesOptions) + plugin.setStringList(listKey, testList, sharedPreferencesOptions) + + plugin.clear(listOf(boolKey, stringKey), sharedPreferencesOptions) + + Assert.assertNull(plugin.getBool(boolKey, sharedPreferencesOptions)) + Assert.assertNull(plugin.getString(stringKey, sharedPreferencesOptions)) + Assert.assertNotNull(plugin.getInt(intKey, sharedPreferencesOptions)) + Assert.assertNotNull(plugin.getDouble(doubleKey, sharedPreferencesOptions)) + Assert.assertNotNull(plugin.getStringList(listKey, sharedPreferencesOptions)) + } + + @Test + fun testGetAllWithAllowListWithSharedPreferences() { + val plugin = pluginSetup(sharedPreferencesOptions) + plugin.setBool(boolKey, testBool, sharedPreferencesOptions) + plugin.setString(stringKey, testString, sharedPreferencesOptions) + plugin.setInt(intKey, testInt, sharedPreferencesOptions) + plugin.setDouble(doubleKey, testDouble, sharedPreferencesOptions) + plugin.setStringList(listKey, testList, sharedPreferencesOptions) + + val all = plugin.getAll(listOf(boolKey, stringKey), sharedPreferencesOptions) Assert.assertEquals(all[boolKey], testBool) Assert.assertEquals(all[stringKey], testString) @@ -177,6 +306,26 @@ internal class SharedPreferencesTest { Assert.assertNull(all[listKey]) } + @Test + fun testSharedPreferencesWithMultipleFiles() { + val plugin = pluginSetup(sharedPreferencesOptions) + val optionsWithNewFile = + SharedPreferencesPigeonOptions(useDataStore = false, fileName = "test_file") + plugin.setInt(intKey, 1, sharedPreferencesOptions) + plugin.setInt(intKey, 2, optionsWithNewFile) + Assert.assertEquals(plugin.getInt(intKey, sharedPreferencesOptions), 1L) + Assert.assertEquals(plugin.getInt(intKey, optionsWithNewFile), 2L) + } + + @Test + fun testSharedPreferencesDefaultFile() { + val defaultPreferences: SharedPreferences = + PreferenceManager.getDefaultSharedPreferences(testContext) + defaultPreferences.edit().putString(stringKey, testString).commit() + val plugin = pluginSetup(sharedPreferencesOptions) + Assert.assertEquals(plugin.getString(stringKey, sharedPreferencesOptions), testString) + } + @Test fun testUnexpectedClassDecodeThrows() { // Only String should be allowed in an encoded list. @@ -188,12 +337,12 @@ internal class SharedPreferencesTest { stream.flush() val badPref = LIST_PREFIX + Base64.encodeToString(byteStream.toByteArray(), 0) - val plugin = pluginSetup() + val plugin = pluginSetup(dataStoreOptions) val badListKey = "badList" // Inject the bad pref as a string, as that is how string lists are stored internally. - plugin.setString(badListKey, badPref, emptyOptions) + plugin.setString(badListKey, badPref, dataStoreOptions) assertThrows(ClassNotFoundException::class.java) { - plugin.getStringList(badListKey, emptyOptions) + plugin.getStringList(badListKey, dataStoreOptions) } } } diff --git a/packages/shared_preferences/shared_preferences_android/example/android/.gitignore b/packages/shared_preferences/shared_preferences_android/example/android/.gitignore index 8e599af9f211..55afd919c659 100644 --- a/packages/shared_preferences/shared_preferences_android/example/android/.gitignore +++ b/packages/shared_preferences/shared_preferences_android/example/android/.gitignore @@ -9,3 +9,5 @@ GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/to/reference-keystore key.properties +**/*.keystore +**/*.jks diff --git a/packages/shared_preferences/shared_preferences_android/example/android/app/build.gradle b/packages/shared_preferences/shared_preferences_android/example/android/app/build.gradle index b2379b24950b..244a92931cf3 100644 --- a/packages/shared_preferences/shared_preferences_android/example/android/app/build.gradle +++ b/packages/shared_preferences/shared_preferences_android/example/android/app/build.gradle @@ -1,3 +1,16 @@ +buildscript { + ext.kotlin_version = '2.1.0' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:8.5.1' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + plugins { id "com.android.application" id "org.jetbrains.kotlin.android" @@ -23,15 +36,25 @@ if (flutterVersionName == null) { } android { - namespace 'io.flutter.plugins.sharedpreferencesexample' + namespace "dev.flutter.plugins.shared_preferences_example" compileSdk flutter.compileSdkVersion + ndkVersion flutter.ndkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = '11' + } sourceSets { main.java.srcDirs += 'src/main/kotlin' } defaultConfig { - applicationId "io.flutter.plugins.sharedpreferencesexample" + applicationId "dev.flutter.plugins.shared_preferences_example" minSdkVersion flutter.minSdkVersion targetSdkVersion 34 versionCode flutterVersionCode.toInteger() @@ -54,4 +77,11 @@ flutter { dependencies { implementation "androidx.datastore:datastore-preferences:1.0.0" + implementation 'androidx.preference:preference:1.2.1' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.espresso:espresso-intents:3.2.0' + androidTestImplementation 'androidx.test:runner:1.2.0' + androidTestImplementation 'androidx.test:rules:1.2.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + api 'androidx.test:core:1.4.0' } diff --git a/packages/shared_preferences/shared_preferences_android/example/android/app/src/androidTest/java/io/flutter/plugins/sharedpreferencesexample/MainActivityTest.java b/packages/shared_preferences/shared_preferences_android/example/android/app/src/androidTest/java/dev/flutter/plugins/shared_preferences_example/MainActivityTest.java similarity index 69% rename from packages/shared_preferences/shared_preferences_android/example/android/app/src/androidTest/java/io/flutter/plugins/sharedpreferencesexample/MainActivityTest.java rename to packages/shared_preferences/shared_preferences_android/example/android/app/src/androidTest/java/dev/flutter/plugins/shared_preferences_example/MainActivityTest.java index 304ee4c33326..20e13ab4115a 100644 --- a/packages/shared_preferences/shared_preferences_android/example/android/app/src/androidTest/java/io/flutter/plugins/sharedpreferencesexample/MainActivityTest.java +++ b/packages/shared_preferences/shared_preferences_android/example/android/app/src/androidTest/java/dev/flutter/plugins/shared_preferences_example/MainActivityTest.java @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package io.flutter.plugins.sharedpreferences; +package dev.flutter.plugins.shared_preferences_example; import androidx.test.rule.ActivityTestRule; import dev.flutter.plugins.integration_test.FlutterTestRunner; -import io.flutter.embedding.android.FlutterActivity; import io.flutter.plugins.DartIntegrationTest; import org.junit.Rule; import org.junit.runner.RunWith; @@ -14,6 +13,5 @@ @DartIntegrationTest @RunWith(FlutterTestRunner.class) public class MainActivityTest { - @Rule - public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); + @Rule public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class); } diff --git a/packages/shared_preferences/shared_preferences_android/example/android/app/src/debug/AndroidManifest.xml b/packages/shared_preferences/shared_preferences_android/example/android/app/src/debug/AndroidManifest.xml index d60d6f69a862..399f6981d5d3 100644 --- a/packages/shared_preferences/shared_preferences_android/example/android/app/src/debug/AndroidManifest.xml +++ b/packages/shared_preferences/shared_preferences_android/example/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/packages/shared_preferences/shared_preferences_android/example/android/app/src/main/AndroidManifest.xml b/packages/shared_preferences/shared_preferences_android/example/android/app/src/main/AndroidManifest.xml index 4288e93f875d..1300cc597640 100644 --- a/packages/shared_preferences/shared_preferences_android/example/android/app/src/main/AndroidManifest.xml +++ b/packages/shared_preferences/shared_preferences_android/example/android/app/src/main/AndroidManifest.xml @@ -1,10 +1,10 @@ - - + - diff --git a/packages/shared_preferences/shared_preferences_android/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/shared_preferences/shared_preferences_android/example/android/gradle/wrapper/gradle-wrapper.properties index b9150adbf128..3c85cfe057a1 100644 --- a/packages/shared_preferences/shared_preferences_android/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/shared_preferences/shared_preferences_android/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Wed Jan 17 19:21:34 PST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/packages/shared_preferences/shared_preferences_android/example/android/settings.gradle b/packages/shared_preferences/shared_preferences_android/example/android/settings.gradle index d056e4db3665..74d52ff12f4f 100644 --- a/packages/shared_preferences/shared_preferences_android/example/android/settings.gradle +++ b/packages/shared_preferences/shared_preferences_android/example/android/settings.gradle @@ -19,7 +19,7 @@ pluginManagement { // See https://github.com/flutter/flutter/blob/master/docs/ecosystem/Plugins-and-Packages-repository-structure.md#gradle-structure for more info. plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.5.1" apply false + id "com.android.application" version "8.5.2" apply false id "org.jetbrains.kotlin.android" version "1.9.0" apply false id "com.google.cloud.artifactregistry.gradle-plugin" version "2.2.1" } diff --git a/packages/shared_preferences/shared_preferences_android/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_android/example/integration_test/shared_preferences_test.dart index 48f451d20a1f..0335b00968b8 100644 --- a/packages/shared_preferences/shared_preferences_android/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_android/example/integration_test/shared_preferences_test.dart @@ -495,208 +495,299 @@ void main() { }); }); - group('shared_preferences_async', () { - const SharedPreferencesAsyncAndroidOptions emptyOptions = - SharedPreferencesAsyncAndroidOptions(); - - const String stringKey = 'testString'; - const String boolKey = 'testBool'; - const String intKey = 'testInt'; - const String doubleKey = 'testDouble'; - const String listKey = 'testList'; - - const String testString = 'hello world'; - const bool testBool = true; - const int testInt = 42; - const double testDouble = 3.14159; - const List testList = ['foo', 'bar']; - - Future getPreferences() async { - final SharedPreferencesAsyncPlatform preferences = - SharedPreferencesAsyncPlatform.instance!; - await preferences.clear( - const ClearPreferencesParameters(filter: PreferencesFilters()), - emptyOptions); - return preferences; - } - - testWidgets('set and get String', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); - - await preferences.setString(stringKey, testString, emptyOptions); - expect(await preferences.getString(stringKey, emptyOptions), testString); - }); + const String stringKey = 'testString'; + const String boolKey = 'testBool'; + const String intKey = 'testInt'; + const String doubleKey = 'testDouble'; + const String listKey = 'testList'; + + const String testString = 'hello world'; + const bool testBool = true; + const int testInt = 42; + const double testDouble = 3.14159; + const List testList = ['foo', 'bar']; + + SharedPreferencesAsyncAndroidOptions getOptions({ + required bool useDataStore, + String? fileName, + }) { + return SharedPreferencesAsyncAndroidOptions( + backend: useDataStore + ? SharedPreferencesAndroidBackendLibrary.DataStore + : SharedPreferencesAndroidBackendLibrary.SharedPreferences, + originalSharedPreferencesOptions: fileName == null + ? null + : AndroidSharedPreferencesStoreOptions(fileName: fileName), + ); + } + + Future clearPreferences( + SharedPreferencesAsyncPlatform preferences, + SharedPreferencesAsyncAndroidOptions options, + ) async { + await preferences.clear( + const ClearPreferencesParameters(filter: PreferencesFilters()), + options); + } + + SharedPreferencesAsyncPlatform getPreferences() { + final SharedPreferencesAsyncPlatform preferences = + SharedPreferencesAsyncPlatform.instance!; + return preferences; + } + + void runAsyncTests(bool useDataStore) { + group('shared_preferences_async', () { + final String backend = useDataStore ? 'DataStore' : 'SharedPreferences'; + + testWidgets('set and get String with $backend', (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); + + await preferences.setString(stringKey, testString, options); + expect(await preferences.getString(stringKey, options), testString); + }); - testWidgets('set and get bool', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + testWidgets('set and get bool with $backend', (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); - await preferences.setBool(boolKey, testBool, emptyOptions); - expect(await preferences.getBool(boolKey, emptyOptions), testBool); - }); + await preferences.setBool(boolKey, testBool, options); + expect(await preferences.getBool(boolKey, options), testBool); + }); - testWidgets('set and get int', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + testWidgets('set and get int with $backend', (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); - await preferences.setInt(intKey, testInt, emptyOptions); - expect(await preferences.getInt(intKey, emptyOptions), testInt); - }); + await preferences.setInt(intKey, testInt, options); + expect(await preferences.getInt(intKey, options), testInt); + }); - testWidgets('set and get double', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + testWidgets('set and get double with $backend', (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); - await preferences.setDouble(doubleKey, testDouble, emptyOptions); - expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); - }); + await preferences.setDouble(doubleKey, testDouble, options); + expect(await preferences.getDouble(doubleKey, options), testDouble); + }); - testWidgets('set and get StringList', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + testWidgets('set and get StringList with $backend', + (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); - await preferences.setStringList(listKey, testList, emptyOptions); - expect(await preferences.getStringList(listKey, emptyOptions), testList); - }); + await preferences.setStringList(listKey, testList, options); + expect(await preferences.getStringList(listKey, options), testList); + }); - testWidgets('getStringList returns mutable list', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + testWidgets('getStringList returns mutable list with $backend', + (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); + + await preferences.setStringList(listKey, testList, options); + final List? list = + await preferences.getStringList(listKey, options); + list?.add('value'); + expect(list?.length, testList.length + 1); + }); - await preferences.setStringList(listKey, testList, emptyOptions); - final List? list = - await preferences.getStringList(listKey, emptyOptions); - list?.add('value'); - expect(list?.length, testList.length + 1); - }); + testWidgets('getPreferences with $backend', (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); + await Future.wait(>[ + preferences.setString(stringKey, testString, options), + preferences.setBool(boolKey, testBool, options), + preferences.setInt(intKey, testInt, options), + preferences.setDouble(doubleKey, testDouble, options), + preferences.setStringList(listKey, testList, options) + ]); - testWidgets('getPreferences', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); + final Map gotAll = await preferences.getPreferences( + const GetPreferencesParameters(filter: PreferencesFilters()), + options, + ); - final Map gotAll = await preferences.getPreferences( - const GetPreferencesParameters(filter: PreferencesFilters()), - emptyOptions, - ); + expect(gotAll.length, 5); + expect(gotAll[stringKey], testString); + expect(gotAll[boolKey], testBool); + expect(gotAll[intKey], testInt); + expect(gotAll[doubleKey], testDouble); + expect(gotAll[listKey], testList); + }); - expect(gotAll.length, 5); - expect(gotAll[stringKey], testString); - expect(gotAll[boolKey], testBool); - expect(gotAll[intKey], testInt); - expect(gotAll[doubleKey], testDouble); - expect(gotAll[listKey], testList); - }); + testWidgets('getPreferences with filter with $backend', + (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); + await Future.wait(>[ + preferences.setString(stringKey, testString, options), + preferences.setBool(boolKey, testBool, options), + preferences.setInt(intKey, testInt, options), + preferences.setDouble(doubleKey, testDouble, options), + preferences.setStringList(listKey, testList, options) + ]); - testWidgets('getPreferences with filter', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); + final Map gotAll = await preferences.getPreferences( + const GetPreferencesParameters( + filter: PreferencesFilters(allowList: {stringKey, boolKey}), + ), + options, + ); - final Map gotAll = await preferences.getPreferences( - const GetPreferencesParameters( - filter: PreferencesFilters(allowList: {stringKey, boolKey}), - ), - emptyOptions, - ); + expect(gotAll.length, 2); + expect(gotAll[stringKey], testString); + expect(gotAll[boolKey], testBool); + }); - expect(gotAll.length, 2); - expect(gotAll[stringKey], testString); - expect(gotAll[boolKey], testBool); - }); + testWidgets('getKeys with $backend', (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); + await Future.wait(>[ + preferences.setString(stringKey, testString, options), + preferences.setBool(boolKey, testBool, options), + preferences.setInt(intKey, testInt, options), + preferences.setDouble(doubleKey, testDouble, options), + preferences.setStringList(listKey, testList, options) + ]); - testWidgets('getKeys', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); + final Set keys = await preferences.getKeys( + const GetPreferencesParameters(filter: PreferencesFilters()), + options, + ); - final Set keys = await preferences.getKeys( - const GetPreferencesParameters(filter: PreferencesFilters()), - emptyOptions, - ); + expect(keys.length, 5); + expect(keys, contains(stringKey)); + expect(keys, contains(boolKey)); + expect(keys, contains(intKey)); + expect(keys, contains(doubleKey)); + expect(keys, contains(listKey)); + }); - expect(keys.length, 5); - expect(keys, contains(stringKey)); - expect(keys, contains(boolKey)); - expect(keys, contains(intKey)); - expect(keys, contains(doubleKey)); - expect(keys, contains(listKey)); - }); + testWidgets('getKeys with filter with $backend', (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); + await Future.wait(>[ + preferences.setString(stringKey, testString, options), + preferences.setBool(boolKey, testBool, options), + preferences.setInt(intKey, testInt, options), + preferences.setDouble(doubleKey, testDouble, options), + preferences.setStringList(listKey, testList, options) + ]); - testWidgets('getKeys with filter', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); + final Set keys = await preferences.getKeys( + const GetPreferencesParameters( + filter: PreferencesFilters(allowList: {stringKey, boolKey}), + ), + options, + ); - final Set keys = await preferences.getKeys( - const GetPreferencesParameters( - filter: PreferencesFilters(allowList: {stringKey, boolKey}), - ), - emptyOptions, - ); + expect(keys.length, 2); + expect(keys, contains(stringKey)); + expect(keys, contains(boolKey)); + }); - expect(keys.length, 2); - expect(keys, contains(stringKey)); - expect(keys, contains(boolKey)); - }); + testWidgets('clear with $backend', (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); + await Future.wait(>[ + preferences.setString(stringKey, testString, options), + preferences.setBool(boolKey, testBool, options), + preferences.setInt(intKey, testInt, options), + preferences.setDouble(doubleKey, testDouble, options), + preferences.setStringList(listKey, testList, options) + ]); - testWidgets('clear', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); + await preferences.clear( + const ClearPreferencesParameters(filter: PreferencesFilters()), + options, + ); - await preferences.clear( - const ClearPreferencesParameters(filter: PreferencesFilters()), - emptyOptions, - ); + expect(await preferences.getString(stringKey, options), null); + expect(await preferences.getBool(boolKey, options), null); + expect(await preferences.getInt(intKey, options), null); + expect(await preferences.getDouble(doubleKey, options), null); + expect(await preferences.getStringList(listKey, options), null); + }); - expect(await preferences.getString(stringKey, emptyOptions), null); - expect(await preferences.getBool(boolKey, emptyOptions), null); - expect(await preferences.getInt(intKey, emptyOptions), null); - expect(await preferences.getDouble(doubleKey, emptyOptions), null); - expect(await preferences.getStringList(listKey, emptyOptions), null); + testWidgets('clear with filter with $backend', (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: useDataStore, fileName: 'notDefault'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options); + await Future.wait(>[ + preferences.setString(stringKey, testString, options), + preferences.setBool(boolKey, testBool, options), + preferences.setInt(intKey, testInt, options), + preferences.setDouble(doubleKey, testDouble, options), + preferences.setStringList(listKey, testList, options) + ]); + await preferences.clear( + const ClearPreferencesParameters( + filter: PreferencesFilters(allowList: {stringKey, boolKey}), + ), + options, + ); + expect(await preferences.getString(stringKey, options), null); + expect(await preferences.getBool(boolKey, options), null); + expect(await preferences.getInt(intKey, options), testInt); + expect(await preferences.getDouble(doubleKey, options), testDouble); + expect(await preferences.getStringList(listKey, options), testList); + }); }); + } + + runAsyncTests(true); + runAsyncTests(false); + + testWidgets('Shared Preferences works with multiple files', + (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options1 = + getOptions(useDataStore: false, fileName: 'file1'); + final SharedPreferencesAsyncAndroidOptions options2 = + getOptions(useDataStore: false, fileName: 'file2'); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + await clearPreferences(preferences, options1); + await clearPreferences(preferences, options2); + + await preferences.setInt(intKey, 1, options1); + await preferences.setInt(intKey, 2, options2); + expect(await preferences.getInt(intKey, options1), 1); + expect(await preferences.getInt(intKey, options2), 2); + }); - testWidgets('clear with filter', (WidgetTester _) async { - final SharedPreferencesAsyncPlatform preferences = await getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); - await preferences.clear( - const ClearPreferencesParameters( - filter: PreferencesFilters(allowList: {stringKey, boolKey}), - ), - emptyOptions, - ); - expect(await preferences.getString(stringKey, emptyOptions), null); - expect(await preferences.getBool(boolKey, emptyOptions), null); - expect(await preferences.getInt(intKey, emptyOptions), testInt); - expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); - expect(await preferences.getStringList(listKey, emptyOptions), testList); - }); + testWidgets('Shared Preferences can read default sharedPreferences', + (WidgetTester _) async { + final SharedPreferencesAsyncAndroidOptions options = + getOptions(useDataStore: false); + final SharedPreferencesAsyncPlatform preferences = getPreferences(); + + expect( + await preferences.getString( + 'thisStringIsWrittenInTheExampleAppJavaCode', options), + 'testString'); }); } diff --git a/packages/shared_preferences/shared_preferences_android/example/lib/main.dart b/packages/shared_preferences/shared_preferences_android/example/lib/main.dart index 5bf8d0609204..e4a0e2121f23 100644 --- a/packages/shared_preferences/shared_preferences_android/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_android/example/lib/main.dart @@ -2,7 +2,7 @@ // 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 +// ignore_for_file: public_member_api_docs, unreachable_from_main import 'package:flutter/material.dart'; import 'package:shared_preferences_android/shared_preferences_android.dart'; @@ -12,6 +12,14 @@ void main() { runApp(const MyApp()); } +// #docregion Android_Options +const SharedPreferencesAsyncAndroidOptions options = + SharedPreferencesAsyncAndroidOptions( + backend: SharedPreferencesAndroidBackendLibrary.SharedPreferences, + originalSharedPreferencesOptions: AndroidSharedPreferencesStoreOptions( + fileName: 'the_name_of_a_file')); +// #enddocregion Android_Options + class MyApp extends StatelessWidget { const MyApp({super.key}); diff --git a/packages/shared_preferences/shared_preferences_android/lib/src/messages_async.g.dart b/packages/shared_preferences/shared_preferences_android/lib/src/messages_async.g.dart index d355cfd916dd..c21b49cca96f 100644 --- a/packages/shared_preferences/shared_preferences_android/lib/src/messages_async.g.dart +++ b/packages/shared_preferences/shared_preferences_android/lib/src/messages_async.g.dart @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v16.0.5), do not edit directly. +// Autogenerated from Pigeon (v22.6.1), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers @@ -20,31 +20,39 @@ PlatformException _createConnectionError(String channelName) { class SharedPreferencesPigeonOptions { SharedPreferencesPigeonOptions({ - this.fileKey, + this.fileName, + this.useDataStore = true, }); - String? fileKey; + String? fileName; + + bool useDataStore; Object encode() { return [ - fileKey, + fileName, + useDataStore, ]; } static SharedPreferencesPigeonOptions decode(Object result) { result as List; return SharedPreferencesPigeonOptions( - fileKey: result[0] as String?, + fileName: result[0] as String?, + useDataStore: result[1]! as bool, ); } } -class _SharedPreferencesAsyncApiCodec extends StandardMessageCodec { - const _SharedPreferencesAsyncApiCodec(); +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is SharedPreferencesPigeonOptions) { - buffer.putUint8(128); + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is SharedPreferencesPigeonOptions) { + buffer.putUint8(129); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -54,7 +62,7 @@ class _SharedPreferencesAsyncApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: + case 129: return SharedPreferencesPigeonOptions.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -66,33 +74,37 @@ class SharedPreferencesAsyncApi { /// Constructor for [SharedPreferencesAsyncApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - SharedPreferencesAsyncApi({BinaryMessenger? binaryMessenger}) - : __pigeon_binaryMessenger = binaryMessenger; - final BinaryMessenger? __pigeon_binaryMessenger; + SharedPreferencesAsyncApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - static const MessageCodec pigeonChannelCodec = - _SharedPreferencesAsyncApiCodec(); + final String pigeonVar_messageChannelSuffix; /// Adds property to shared preferences data set of type bool. Future setBool( String key, bool value, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setBool'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setBool$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel + final List? pigeonVar_replyList = await pigeonVar_channel .send([key, value, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -102,23 +114,23 @@ class SharedPreferencesAsyncApi { /// Adds property to shared preferences data set of type String. Future setString( String key, String value, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setString'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setString$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel + final List? pigeonVar_replyList = await pigeonVar_channel .send([key, value, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -128,23 +140,23 @@ class SharedPreferencesAsyncApi { /// Adds property to shared preferences data set of type int. Future setInt( String key, int value, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setInt'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setInt$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel + final List? pigeonVar_replyList = await pigeonVar_channel .send([key, value, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -154,23 +166,23 @@ class SharedPreferencesAsyncApi { /// Adds property to shared preferences data set of type double. Future setDouble( String key, double value, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setDouble'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setDouble$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel + final List? pigeonVar_replyList = await pigeonVar_channel .send([key, value, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -178,25 +190,25 @@ class SharedPreferencesAsyncApi { } /// Adds property to shared preferences data set of type List. - Future setStringList(String key, List value, + Future setStringList(String key, List value, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setStringList'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.setStringList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel + final List? pigeonVar_replyList = await pigeonVar_channel .send([key, value, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -206,153 +218,153 @@ class SharedPreferencesAsyncApi { /// Gets individual String value stored with [key], if any. Future getString( String key, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getString'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getString$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([key, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([key, options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (__pigeon_replyList[0] as String?); + return (pigeonVar_replyList[0] as String?); } } /// Gets individual void value stored with [key], if any. Future getBool( String key, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getBool'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getBool$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([key, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([key, options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (__pigeon_replyList[0] as bool?); + return (pigeonVar_replyList[0] as bool?); } } /// Gets individual double value stored with [key], if any. Future getDouble( String key, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getDouble'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getDouble$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([key, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([key, options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (__pigeon_replyList[0] as double?); + return (pigeonVar_replyList[0] as double?); } } /// Gets individual int value stored with [key], if any. Future getInt( String key, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getInt'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getInt$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([key, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([key, options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (__pigeon_replyList[0] as int?); + return (pigeonVar_replyList[0] as int?); } } /// Gets individual List value stored with [key], if any. - Future?> getStringList( + Future?> getStringList( String key, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getStringList'; - final BasicMessageChannel __pigeon_channel = + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getStringList$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = - await __pigeon_channel.send([key, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + final List? pigeonVar_replyList = + await pigeonVar_channel.send([key, options]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { - return (__pigeon_replyList[0] as List?)?.cast(); + return (pigeonVar_replyList[0] as List?)?.cast(); } } /// Removes all properties from shared preferences data set with matching prefix. Future clear( - List? allowList, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.clear'; - final BasicMessageChannel __pigeon_channel = + List? allowList, SharedPreferencesPigeonOptions options) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.clear$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel + final List? pigeonVar_replyList = await pigeonVar_channel .send([allowList, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); } else { return; @@ -360,65 +372,65 @@ class SharedPreferencesAsyncApi { } /// Gets all properties from shared preferences data set with matching prefix. - Future> getAll( - List? allowList, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getAll'; - final BasicMessageChannel __pigeon_channel = + Future> getAll( + List? allowList, SharedPreferencesPigeonOptions options) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getAll$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel + final List? pigeonVar_replyList = await pigeonVar_channel .send([allowList, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (__pigeon_replyList[0] == null) { + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as Map?)! - .cast(); + return (pigeonVar_replyList[0] as Map?)! + .cast(); } } /// Gets all properties from shared preferences data set with matching prefix. - Future> getKeys( - List? allowList, SharedPreferencesPigeonOptions options) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getKeys'; - final BasicMessageChannel __pigeon_channel = + Future> getKeys( + List? allowList, SharedPreferencesPigeonOptions options) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.shared_preferences_android.SharedPreferencesAsyncApi.getKeys$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( - __pigeon_channelName, + pigeonVar_channelName, pigeonChannelCodec, - binaryMessenger: __pigeon_binaryMessenger, + binaryMessenger: pigeonVar_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel + final List? pigeonVar_replyList = await pigeonVar_channel .send([allowList, options]) as List?; - if (__pigeon_replyList == null) { - throw _createConnectionError(__pigeon_channelName); - } else if (__pigeon_replyList.length > 1) { + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { throw PlatformException( - code: __pigeon_replyList[0]! as String, - message: __pigeon_replyList[1] as String?, - details: __pigeon_replyList[2], + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], ); - } else if (__pigeon_replyList[0] == null) { + } else if (pigeonVar_replyList[0] == null) { throw PlatformException( code: 'null-error', message: 'Host platform returned null value for non-null return value.', ); } else { - return (__pigeon_replyList[0] as List?)!.cast(); + return (pigeonVar_replyList[0] as List?)!.cast(); } } } diff --git a/packages/shared_preferences/shared_preferences_android/lib/src/shared_preferences_async_android.dart b/packages/shared_preferences/shared_preferences_android/lib/src/shared_preferences_async_android.dart index 7b3f1cb7b352..2b6dcd5bcaa1 100644 --- a/packages/shared_preferences/shared_preferences_android/lib/src/shared_preferences_async_android.dart +++ b/packages/shared_preferences/shared_preferences_android/lib/src/shared_preferences_async_android.dart @@ -18,10 +18,16 @@ base class SharedPreferencesAsyncAndroid extends SharedPreferencesAsyncPlatform { /// Creates a new plugin implementation instance. SharedPreferencesAsyncAndroid({ - @visibleForTesting SharedPreferencesAsyncApi? api, - }) : _api = api ?? SharedPreferencesAsyncApi(); + @visibleForTesting SharedPreferencesAsyncApi? dataStoreApi, + @visibleForTesting SharedPreferencesAsyncApi? sharedPreferencesApi, + }) : _dataStoreApi = dataStoreApi ?? + SharedPreferencesAsyncApi(messageChannelSuffix: 'data_store'), + _sharedPreferencesApi = sharedPreferencesApi ?? + SharedPreferencesAsyncApi( + messageChannelSuffix: 'shared_preferences'); - final SharedPreferencesAsyncApi _api; + final SharedPreferencesAsyncApi _dataStoreApi; + final SharedPreferencesAsyncApi _sharedPreferencesApi; /// Registers this class as the default instance of [SharedPreferencesAsyncPlatform]. static void registerWith() { @@ -31,22 +37,34 @@ base class SharedPreferencesAsyncAndroid /// Returns a SharedPreferencesPigeonOptions for sending to platform. SharedPreferencesPigeonOptions _convertOptionsToPigeonOptions( SharedPreferencesOptions options) { + if (options is SharedPreferencesAsyncAndroidOptions) { + return SharedPreferencesPigeonOptions( + fileName: options.originalSharedPreferencesOptions?.fileName, + useDataStore: + options.backend == SharedPreferencesAndroidBackendLibrary.DataStore, + ); + } return SharedPreferencesPigeonOptions(); } + SharedPreferencesAsyncApi _getApiForBackend( + SharedPreferencesPigeonOptions options) { + return options.useDataStore ? _dataStoreApi : _sharedPreferencesApi; + } + @override Future> getKeys( GetPreferencesParameters parameters, SharedPreferencesOptions options, ) async { final PreferencesFilters filter = parameters.filter; - // TODO(tarrinneal): Remove cast once https://github.com/flutter/flutter/issues/97848 - // is fixed. In practice, the values will never be null, and the native implementation assumes that. - return (await _api.getKeys( + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); + return (await api.getKeys( filter.allowList?.toList(), - _convertOptionsToPigeonOptions(options), + pigeonOptions, )) - .cast() .toSet(); } @@ -60,8 +78,11 @@ base class SharedPreferencesAsyncAndroid throw ArgumentError( 'StorageError: This string cannot be stored as it clashes with special identifier prefixes'); } + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); - return _api.setString(key, value, _convertOptionsToPigeonOptions(options)); + return api.setString(key, value, pigeonOptions); } @override @@ -70,7 +91,10 @@ base class SharedPreferencesAsyncAndroid int value, SharedPreferencesOptions options, ) async { - return _api.setInt(key, value, _convertOptionsToPigeonOptions(options)); + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); + return api.setInt(key, value, pigeonOptions); } @override @@ -79,7 +103,10 @@ base class SharedPreferencesAsyncAndroid double value, SharedPreferencesOptions options, ) async { - return _api.setDouble(key, value, _convertOptionsToPigeonOptions(options)); + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); + return api.setDouble(key, value, pigeonOptions); } @override @@ -88,7 +115,10 @@ base class SharedPreferencesAsyncAndroid bool value, SharedPreferencesOptions options, ) async { - return _api.setBool(key, value, _convertOptionsToPigeonOptions(options)); + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); + return api.setBool(key, value, pigeonOptions); } @override @@ -97,8 +127,10 @@ base class SharedPreferencesAsyncAndroid List value, SharedPreferencesOptions options, ) async { - return _api.setStringList( - key, value, _convertOptionsToPigeonOptions(options)); + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); + return api.setStringList(key, value, pigeonOptions); } @override @@ -106,8 +138,11 @@ base class SharedPreferencesAsyncAndroid String key, SharedPreferencesOptions options, ) async { - return _convertKnownExceptions(() async => - _api.getString(key, _convertOptionsToPigeonOptions(options))); + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); + return _convertKnownExceptions( + () async => api.getString(key, pigeonOptions)); } @override @@ -115,8 +150,11 @@ base class SharedPreferencesAsyncAndroid String key, SharedPreferencesOptions options, ) async { + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); return _convertKnownExceptions( - () async => _api.getBool(key, _convertOptionsToPigeonOptions(options))); + () async => api.getBool(key, pigeonOptions)); } @override @@ -124,8 +162,11 @@ base class SharedPreferencesAsyncAndroid String key, SharedPreferencesOptions options, ) async { - return _convertKnownExceptions(() async => - _api.getDouble(key, _convertOptionsToPigeonOptions(options))); + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); + return _convertKnownExceptions( + () async => api.getDouble(key, pigeonOptions)); } @override @@ -133,8 +174,11 @@ base class SharedPreferencesAsyncAndroid String key, SharedPreferencesOptions options, ) async { + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); return _convertKnownExceptions( - () async => _api.getInt(key, _convertOptionsToPigeonOptions(options))); + () async => api.getInt(key, pigeonOptions)); } @override @@ -142,12 +186,13 @@ base class SharedPreferencesAsyncAndroid String key, SharedPreferencesOptions options, ) async { + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); // TODO(tarrinneal): Remove cast once https://github.com/flutter/flutter/issues/97848 // is fixed. In practice, the values will never be null, and the native implementation assumes that. return _convertKnownExceptions>(() async => - (await _api.getStringList(key, _convertOptionsToPigeonOptions(options))) - ?.cast() - .toList()); + (await api.getStringList(key, pigeonOptions))?.cast().toList()); } Future _convertKnownExceptions(Future Function() method) async { @@ -169,9 +214,12 @@ base class SharedPreferencesAsyncAndroid SharedPreferencesOptions options, ) async { final PreferencesFilters filter = parameters.filter; - return _api.clear( + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); + return api.clear( filter.allowList?.toList(), - _convertOptionsToPigeonOptions(options), + pigeonOptions, ); } @@ -181,16 +229,53 @@ base class SharedPreferencesAsyncAndroid SharedPreferencesOptions options, ) async { final PreferencesFilters filter = parameters.filter; - final Map data = await _api.getAll( + final SharedPreferencesPigeonOptions pigeonOptions = + _convertOptionsToPigeonOptions(options); + final SharedPreferencesAsyncApi api = _getApiForBackend(pigeonOptions); + final Map data = await api.getAll( filter.allowList?.toList(), - _convertOptionsToPigeonOptions(options), + pigeonOptions, ); return data.cast(); } } +/// Used to identify which Android library should be used on the backend of this call. +enum SharedPreferencesAndroidBackendLibrary { + /// Represents the newer DataStore Preferences library. + DataStore, + + /// Represents the older SharedPreferences library. + SharedPreferences, +} + /// Options for the Android specific SharedPreferences plugin. class SharedPreferencesAsyncAndroidOptions extends SharedPreferencesOptions { /// Constructor for SharedPreferencesAsyncAndroidOptions. - const SharedPreferencesAsyncAndroidOptions(); + const SharedPreferencesAsyncAndroidOptions({ + this.backend = SharedPreferencesAndroidBackendLibrary.DataStore, + this.originalSharedPreferencesOptions, + }); + + /// Which backend should be used for this method call. + final SharedPreferencesAndroidBackendLibrary backend; + + /// These options define how the `SharedPreferences` backend should behave. + /// + /// Any options in this field will be ignored unless the backend that is selected + /// is `SharedPreferences`. + final AndroidSharedPreferencesStoreOptions? originalSharedPreferencesOptions; +} + +/// Options necessary for defining the use of the original `SharedPreferences` +/// library. +/// +/// These options are only ever used with the original `SharedPreferences` and +/// have no purpose when using the default DataStore Preferences. +class AndroidSharedPreferencesStoreOptions { + /// Constructor for AndroidSharedPreferencesStoreOptions. + const AndroidSharedPreferencesStoreOptions({this.fileName}); + + /// The name of the file in which the preferences are stored. + final String? fileName; } diff --git a/packages/shared_preferences/shared_preferences_android/pigeons/messages_async.dart b/packages/shared_preferences/shared_preferences_android/pigeons/messages_async.dart index 5334cc042f5f..9334123482b5 100644 --- a/packages/shared_preferences/shared_preferences_android/pigeons/messages_async.dart +++ b/packages/shared_preferences/shared_preferences_android/pigeons/messages_async.dart @@ -17,9 +17,11 @@ import 'package:pigeon/pigeon.dart'; )) class SharedPreferencesPigeonOptions { SharedPreferencesPigeonOptions({ - this.fileKey, + this.fileName, + this.useDataStore = true, }); - String? fileKey; + String? fileName; + bool useDataStore; } @HostApi(dartHostTestHandler: 'TestSharedPreferencesAsyncApi') diff --git a/packages/shared_preferences/shared_preferences_android/pubspec.yaml b/packages/shared_preferences/shared_preferences_android/pubspec.yaml index c161df41512f..594d763c6f8a 100644 --- a/packages/shared_preferences/shared_preferences_android/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_android/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences_android description: Android implementation of the shared_preferences plugin repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.3.4 +version: 2.4.0 environment: sdk: ^3.5.0 @@ -25,7 +25,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pigeon: ^16.0.4 + pigeon: ^22.6.0 topics: - persistence diff --git a/packages/shared_preferences/shared_preferences_android/test/shared_preferences_async_test.dart b/packages/shared_preferences/shared_preferences_android/test/shared_preferences_async_test.dart index 45ee340a7cfe..fd2907e164b1 100755 --- a/packages/shared_preferences/shared_preferences_android/test/shared_preferences_async_test.dart +++ b/packages/shared_preferences/shared_preferences_android/test/shared_preferences_async_test.dart @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// ignore_for_file: non_constant_identifier_names + +import 'package:flutter/src/services/binary_messenger.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences_android/shared_preferences_android.dart'; import 'package:shared_preferences_android/src/messages_async.g.dart'; @@ -22,185 +25,216 @@ void main() { const double testDouble = 3.14159; const List testList = ['foo', 'bar']; - const SharedPreferencesAsyncAndroidOptions emptyOptions = - SharedPreferencesAsyncAndroidOptions(); - - SharedPreferencesAsyncAndroid getPreferences() { + SharedPreferencesAsyncAndroid getPreferences(bool useDataStore) { final _FakeSharedPreferencesApi api = _FakeSharedPreferencesApi(); final SharedPreferencesAsyncAndroid preferences = - SharedPreferencesAsyncAndroid(api: api); + SharedPreferencesAsyncAndroid( + dataStoreApi: api, + sharedPreferencesApi: api, + ); return preferences; } - test('set and get String', () async { - final SharedPreferencesAsyncAndroid preferences = getPreferences(); - - await preferences.setString(stringKey, testString, emptyOptions); - expect(await preferences.getString(stringKey, emptyOptions), testString); - }); - - test('set and get bool', () async { - final SharedPreferencesAsyncAndroid preferences = getPreferences(); - - await preferences.setBool(boolKey, testBool, emptyOptions); - expect(await preferences.getBool(boolKey, emptyOptions), testBool); - }); - - test('set and get int', () async { - final SharedPreferencesAsyncAndroid preferences = getPreferences(); - - await preferences.setInt(intKey, testInt, emptyOptions); - expect(await preferences.getInt(intKey, emptyOptions), testInt); - }); - - test('set and get double', () async { - final SharedPreferencesAsyncAndroid preferences = getPreferences(); - - await preferences.setDouble(doubleKey, testDouble, emptyOptions); - expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); - }); - - test('set and get StringList', () async { - final SharedPreferencesAsyncAndroid preferences = getPreferences(); + void runTests(bool useDataStore) { + final String backend = useDataStore ? 'DataStore' : 'SharedPreferences'; - await preferences.setStringList(listKey, testList, emptyOptions); - expect(await preferences.getStringList(listKey, emptyOptions), testList); - }); - - test('getPreferences', () async { - final SharedPreferencesAsyncAndroid preferences = getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); + final SharedPreferencesAsyncAndroidOptions emptyOptions = + SharedPreferencesAsyncAndroidOptions( + backend: useDataStore + ? SharedPreferencesAndroidBackendLibrary.DataStore + : SharedPreferencesAndroidBackendLibrary.SharedPreferences, + ); - final Map gotAll = await preferences.getPreferences( + test('set and get String with $backend', () async { + final SharedPreferencesAsyncAndroid preferences = + getPreferences(useDataStore); + + await preferences.setString(stringKey, testString, emptyOptions); + expect(await preferences.getString(stringKey, emptyOptions), testString); + }); + + test('set and get bool with $backend', () async { + final SharedPreferencesAsyncAndroid preferences = + getPreferences(useDataStore); + + await preferences.setBool(boolKey, testBool, emptyOptions); + expect(await preferences.getBool(boolKey, emptyOptions), testBool); + }); + + test('set and get int with $backend', () async { + final SharedPreferencesAsyncAndroid preferences = + getPreferences(useDataStore); + + await preferences.setInt(intKey, testInt, emptyOptions); + expect(await preferences.getInt(intKey, emptyOptions), testInt); + }); + + test('set and get double with $backend', () async { + final SharedPreferencesAsyncAndroid preferences = + getPreferences(useDataStore); + + await preferences.setDouble(doubleKey, testDouble, emptyOptions); + expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); + }); + + test('set and get StringList with $backend', () async { + final SharedPreferencesAsyncAndroid preferences = + getPreferences(useDataStore); + + await preferences.setStringList(listKey, testList, emptyOptions); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + + test('getPreferences with $backend', () async { + final SharedPreferencesAsyncAndroid preferences = + getPreferences(useDataStore); + await Future.wait(>[ + preferences.setString(stringKey, testString, emptyOptions), + preferences.setBool(boolKey, testBool, emptyOptions), + preferences.setInt(intKey, testInt, emptyOptions), + preferences.setDouble(doubleKey, testDouble, emptyOptions), + preferences.setStringList(listKey, testList, emptyOptions) + ]); + + final Map gotAll = await preferences.getPreferences( + const GetPreferencesParameters(filter: PreferencesFilters()), + emptyOptions); + + expect(gotAll.length, 5); + expect(gotAll[stringKey], testString); + expect(gotAll[boolKey], testBool); + expect(gotAll[intKey], testInt); + expect(gotAll[doubleKey], testDouble); + expect(gotAll[listKey], testList); + }); + + test('getPreferences with filter with $backend', () async { + final SharedPreferencesAsyncAndroid preferences = + getPreferences(useDataStore); + await Future.wait(>[ + preferences.setString(stringKey, testString, emptyOptions), + preferences.setBool(boolKey, testBool, emptyOptions), + preferences.setInt(intKey, testInt, emptyOptions), + preferences.setDouble(doubleKey, testDouble, emptyOptions), + preferences.setStringList(listKey, testList, emptyOptions) + ]); + + final Map gotAll = await preferences.getPreferences( + const GetPreferencesParameters( + filter: + PreferencesFilters(allowList: {stringKey, boolKey})), + emptyOptions); + + expect(gotAll.length, 2); + expect(gotAll[stringKey], testString); + expect(gotAll[boolKey], testBool); + }); + + test('getKeys with $backend', () async { + final SharedPreferencesAsyncAndroid preferences = + getPreferences(useDataStore); + await Future.wait(>[ + preferences.setString(stringKey, testString, emptyOptions), + preferences.setBool(boolKey, testBool, emptyOptions), + preferences.setInt(intKey, testInt, emptyOptions), + preferences.setDouble(doubleKey, testDouble, emptyOptions), + preferences.setStringList(listKey, testList, emptyOptions) + ]); + + final Set keys = await preferences.getKeys( const GetPreferencesParameters(filter: PreferencesFilters()), - emptyOptions); - - expect(gotAll.length, 5); - expect(gotAll[stringKey], testString); - expect(gotAll[boolKey], testBool); - expect(gotAll[intKey], testInt); - expect(gotAll[doubleKey], testDouble); - expect(gotAll[listKey], testList); - }); - - test('getPreferences with filter', () async { - final SharedPreferencesAsyncAndroid preferences = getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); - - final Map gotAll = await preferences.getPreferences( + emptyOptions, + ); + + expect(keys.length, 5); + expect(keys, contains(stringKey)); + expect(keys, contains(boolKey)); + expect(keys, contains(intKey)); + expect(keys, contains(doubleKey)); + expect(keys, contains(listKey)); + }); + + test('getKeys with filter with $backend', () async { + final SharedPreferencesAsyncAndroid preferences = + getPreferences(useDataStore); + await Future.wait(>[ + preferences.setString(stringKey, testString, emptyOptions), + preferences.setBool(boolKey, testBool, emptyOptions), + preferences.setInt(intKey, testInt, emptyOptions), + preferences.setDouble(doubleKey, testDouble, emptyOptions), + preferences.setStringList(listKey, testList, emptyOptions) + ]); + + final Set keys = await preferences.getKeys( const GetPreferencesParameters( - filter: - PreferencesFilters(allowList: {stringKey, boolKey})), - emptyOptions); - - expect(gotAll.length, 2); - expect(gotAll[stringKey], testString); - expect(gotAll[boolKey], testBool); - }); - - test('getKeys', () async { - final SharedPreferencesAsyncAndroid preferences = getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); - - final Set keys = await preferences.getKeys( - const GetPreferencesParameters(filter: PreferencesFilters()), - emptyOptions, - ); - - expect(keys.length, 5); - expect(keys, contains(stringKey)); - expect(keys, contains(boolKey)); - expect(keys, contains(intKey)); - expect(keys, contains(doubleKey)); - expect(keys, contains(listKey)); - }); - - test('getKeys with filter', () async { - final SharedPreferencesAsyncAndroid preferences = getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); - - final Set keys = await preferences.getKeys( - const GetPreferencesParameters( - filter: PreferencesFilters(allowList: {stringKey, boolKey}), - ), - emptyOptions, - ); + filter: PreferencesFilters(allowList: {stringKey, boolKey}), + ), + emptyOptions, + ); + + expect(keys.length, 2); + expect(keys, contains(stringKey)); + expect(keys, contains(boolKey)); + }); + + test('clear with $backend', () async { + final SharedPreferencesAsyncAndroid preferences = + getPreferences(useDataStore); + await Future.wait(>[ + preferences.setString(stringKey, testString, emptyOptions), + preferences.setBool(boolKey, testBool, emptyOptions), + preferences.setInt(intKey, testInt, emptyOptions), + preferences.setDouble(doubleKey, testDouble, emptyOptions), + preferences.setStringList(listKey, testList, emptyOptions) + ]); + await preferences.clear( + const ClearPreferencesParameters(filter: PreferencesFilters()), + emptyOptions); + expect(await preferences.getString(stringKey, emptyOptions), null); + expect(await preferences.getBool(boolKey, emptyOptions), null); + expect(await preferences.getInt(intKey, emptyOptions), null); + expect(await preferences.getDouble(doubleKey, emptyOptions), null); + expect(await preferences.getStringList(listKey, emptyOptions), null); + }); + + test('clear with filter with $backend', () async { + final SharedPreferencesAsyncAndroid preferences = + getPreferences(useDataStore); + await Future.wait(>[ + preferences.setString(stringKey, testString, emptyOptions), + preferences.setBool(boolKey, testBool, emptyOptions), + preferences.setInt(intKey, testInt, emptyOptions), + preferences.setDouble(doubleKey, testDouble, emptyOptions), + preferences.setStringList(listKey, testList, emptyOptions) + ]); + await preferences.clear( + const ClearPreferencesParameters( + filter: PreferencesFilters(allowList: {stringKey, boolKey}), + ), + emptyOptions, + ); + expect(await preferences.getString(stringKey, emptyOptions), null); + expect(await preferences.getBool(boolKey, emptyOptions), null); + expect(await preferences.getInt(intKey, emptyOptions), testInt); + expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); + expect(await preferences.getStringList(listKey, emptyOptions), testList); + }); + } - expect(keys.length, 2); - expect(keys, contains(stringKey)); - expect(keys, contains(boolKey)); - }); - - test('clear', () async { - final SharedPreferencesAsyncAndroid preferences = getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); - await preferences.clear( - const ClearPreferencesParameters(filter: PreferencesFilters()), - emptyOptions); - expect(await preferences.getString(stringKey, emptyOptions), null); - expect(await preferences.getBool(boolKey, emptyOptions), null); - expect(await preferences.getInt(intKey, emptyOptions), null); - expect(await preferences.getDouble(doubleKey, emptyOptions), null); - expect(await preferences.getStringList(listKey, emptyOptions), null); - }); - - test('clear with filter', () async { - final SharedPreferencesAsyncAndroid preferences = getPreferences(); - await Future.wait(>[ - preferences.setString(stringKey, testString, emptyOptions), - preferences.setBool(boolKey, testBool, emptyOptions), - preferences.setInt(intKey, testInt, emptyOptions), - preferences.setDouble(doubleKey, testDouble, emptyOptions), - preferences.setStringList(listKey, testList, emptyOptions) - ]); - await preferences.clear( - const ClearPreferencesParameters( - filter: PreferencesFilters(allowList: {stringKey, boolKey}), - ), - emptyOptions, - ); - expect(await preferences.getString(stringKey, emptyOptions), null); - expect(await preferences.getBool(boolKey, emptyOptions), null); - expect(await preferences.getInt(intKey, emptyOptions), testInt); - expect(await preferences.getDouble(doubleKey, emptyOptions), testDouble); - expect(await preferences.getStringList(listKey, emptyOptions), testList); - }); + runTests(true); + runTests(false); } class _FakeSharedPreferencesApi implements SharedPreferencesAsyncApi { final Map items = {}; + @override + BinaryMessenger? get pigeonVar_binaryMessenger => throw UnimplementedError(); + + @override + String get pigeonVar_messageChannelSuffix => throw UnimplementedError(); + @override Future clear( List? allowList, SharedPreferencesPigeonOptions options) async { @@ -214,7 +248,7 @@ class _FakeSharedPreferencesApi implements SharedPreferencesAsyncApi { } @override - Future> getAll( + Future> getAll( List? allowList, SharedPreferencesPigeonOptions options) async { final Map filteredItems = {...items}; if (allowList != null) { @@ -242,7 +276,7 @@ class _FakeSharedPreferencesApi implements SharedPreferencesAsyncApi { } @override - Future> getKeys( + Future> getKeys( List? allowList, SharedPreferencesPigeonOptions options) async { final List filteredItems = items.keys.toList(); if (allowList != null) { @@ -258,7 +292,7 @@ class _FakeSharedPreferencesApi implements SharedPreferencesAsyncApi { } @override - Future?> getStringList( + Future?> getStringList( String key, SharedPreferencesPigeonOptions options) async { return items[key] as List?; } diff --git a/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md b/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md index 42722fe4b182..6af9743b2e0a 100644 --- a/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.5.4 + +* Updates Pigeon to fix lint error. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.5.3 * Updates Pigeon for non-nullable collection type support. diff --git a/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/messages.g.swift b/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/messages.g.swift index 275de0921d50..665ea2e5ed6b 100644 --- a/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/messages.g.swift +++ b/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/messages.g.swift @@ -86,7 +86,7 @@ struct SharedPreferencesPigeonOptions { } } -private class messagesPigeonCodecReader: FlutterStandardReader { +private class MessagesPigeonCodecReader: FlutterStandardReader { override func readValue(ofType type: UInt8) -> Any? { switch type { case 129: @@ -97,7 +97,7 @@ private class messagesPigeonCodecReader: FlutterStandardReader { } } -private class messagesPigeonCodecWriter: FlutterStandardWriter { +private class MessagesPigeonCodecWriter: FlutterStandardWriter { override func writeValue(_ value: Any) { if let value = value as? SharedPreferencesPigeonOptions { super.writeByte(129) @@ -108,18 +108,18 @@ private class messagesPigeonCodecWriter: FlutterStandardWriter { } } -private class messagesPigeonCodecReaderWriter: FlutterStandardReaderWriter { +private class MessagesPigeonCodecReaderWriter: FlutterStandardReaderWriter { override func reader(with data: Data) -> FlutterStandardReader { - return messagesPigeonCodecReader(data: data) + return MessagesPigeonCodecReader(data: data) } override func writer(with data: NSMutableData) -> FlutterStandardWriter { - return messagesPigeonCodecWriter(data: data) + return MessagesPigeonCodecWriter(data: data) } } -class messagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { - static let shared = messagesPigeonCodec(readerWriter: messagesPigeonCodecReaderWriter()) +class MessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { + static let shared = MessagesPigeonCodec(readerWriter: MessagesPigeonCodecReaderWriter()) } /// Generated protocol from Pigeon that represents a handler of messages from Flutter. @@ -134,7 +134,7 @@ protocol LegacyUserDefaultsApi { /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. class LegacyUserDefaultsApiSetup { - static var codec: FlutterStandardMessageCodec { messagesPigeonCodec.shared } + static var codec: FlutterStandardMessageCodec { MessagesPigeonCodec.shared } /// Sets up an instance of `LegacyUserDefaultsApi` to handle messages through the `binaryMessenger`. static func setUp( binaryMessenger: FlutterBinaryMessenger, api: LegacyUserDefaultsApi?, @@ -272,7 +272,7 @@ protocol UserDefaultsApi { /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. class UserDefaultsApiSetup { - static var codec: FlutterStandardMessageCodec { messagesPigeonCodec.shared } + static var codec: FlutterStandardMessageCodec { MessagesPigeonCodec.shared } /// Sets up an instance of `UserDefaultsApi` to handle messages through the `binaryMessenger`. static func setUp( binaryMessenger: FlutterBinaryMessenger, api: UserDefaultsApi?, diff --git a/packages/shared_preferences/shared_preferences_foundation/example/macos/Runner/DebugProfile.entitlements b/packages/shared_preferences/shared_preferences_foundation/example/macos/Runner/DebugProfile.entitlements index e635cd9a4bf4..dddb8a30c851 100644 --- a/packages/shared_preferences/shared_preferences_foundation/example/macos/Runner/DebugProfile.entitlements +++ b/packages/shared_preferences/shared_preferences_foundation/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/shared_preferences/shared_preferences_foundation/example/macos/Runner/Release.entitlements b/packages/shared_preferences/shared_preferences_foundation/example/macos/Runner/Release.entitlements index 0218c441b4e3..852fa1a4728a 100644 --- a/packages/shared_preferences/shared_preferences_foundation/example/macos/Runner/Release.entitlements +++ b/packages/shared_preferences/shared_preferences_foundation/example/macos/Runner/Release.entitlements @@ -3,7 +3,6 @@ com.apple.security.app-sandbox - - + diff --git a/packages/shared_preferences/shared_preferences_foundation/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_foundation/example/pubspec.yaml index ac1ef988c6d8..931e2c7ac7db 100644 --- a/packages/shared_preferences/shared_preferences_foundation/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_foundation/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Testbed for the shared_preferences_foundation implementation. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/shared_preferences/shared_preferences_foundation/pubspec.yaml b/packages/shared_preferences/shared_preferences_foundation/pubspec.yaml index 50b73b1264bb..915f1c5707a8 100644 --- a/packages/shared_preferences/shared_preferences_foundation/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_foundation/pubspec.yaml @@ -2,11 +2,11 @@ name: shared_preferences_foundation description: iOS and macOS implementation of the shared_preferences plugin. repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_foundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.5.3 +version: 2.5.4 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md index 43c46f51a84f..d769156bd35e 100644 --- a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.4.1 * Fixes `getStringList` returning immutable list. diff --git a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml index 35da7cfab3c9..0bf7bd8255b9 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the shared_preferences_linux plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml index c43a21bdb95f..065e439e44b6 100644 --- a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.4.1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md index b52c8c962bfc..36fa52e4bc8a 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 2.4.1 diff --git a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml index 6161a5882e1d..d8df0ac2bc60 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.4.1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md index d2cf5d62ace9..c6ce11b9f6eb 100644 --- a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.4.1 * Fixes `getStringList` returning immutable list. diff --git a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml index dbbf7c7530ef..031474415774 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the shared_preferences_windows plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index 59c3274488b4..6c4f02e3e006 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.4.1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/standard_message_codec/CHANGELOG.md b/packages/standard_message_codec/CHANGELOG.md index 9da834b04cba..a87ddfe2a326 100644 --- a/packages/standard_message_codec/CHANGELOG.md +++ b/packages/standard_message_codec/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 0.0.1+4 diff --git a/packages/standard_message_codec/example/pubspec.yaml b/packages/standard_message_codec/example/pubspec.yaml index 40b4f7fc7f04..24edd8179688 100644 --- a/packages/standard_message_codec/example/pubspec.yaml +++ b/packages/standard_message_codec/example/pubspec.yaml @@ -4,7 +4,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: standard_message_codec: diff --git a/packages/standard_message_codec/pubspec.yaml b/packages/standard_message_codec/pubspec.yaml index f27690918b32..60343a8d508f 100644 --- a/packages/standard_message_codec/pubspec.yaml +++ b/packages/standard_message_codec/pubspec.yaml @@ -5,7 +5,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/standard_mess issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Astandard_message_codec environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dev_dependencies: test: ^1.16.0 diff --git a/packages/two_dimensional_scrollables/CHANGELOG.md b/packages/two_dimensional_scrollables/CHANGELOG.md index 31ecdfdcdb66..cb4b895d5843 100644 --- a/packages/two_dimensional_scrollables/CHANGELOG.md +++ b/packages/two_dimensional_scrollables/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 0.3.3 * Fixes an issue where collapsing nodes in the TreeView didn't work correctly. diff --git a/packages/two_dimensional_scrollables/example/pubspec.yaml b/packages/two_dimensional_scrollables/example/pubspec.yaml index c7786ae10c6f..b96157acb18c 100644 --- a/packages/two_dimensional_scrollables/example/pubspec.yaml +++ b/packages/two_dimensional_scrollables/example/pubspec.yaml @@ -6,8 +6,8 @@ publish_to: 'none' version: 2.0.0 environment: - sdk: '>=3.3.0 <4.0.0' - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/two_dimensional_scrollables/pubspec.yaml b/packages/two_dimensional_scrollables/pubspec.yaml index 3cd575a8c76a..9cdd89917b33 100644 --- a/packages/two_dimensional_scrollables/pubspec.yaml +++ b/packages/two_dimensional_scrollables/pubspec.yaml @@ -5,8 +5,8 @@ repository: https://github.com/flutter/packages/tree/main/packages/two_dimension issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+two_dimensional_scrollables%22+ environment: - sdk: '>=3.3.0 <4.0.0' - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 859646fbe7b3..83f67b28e596 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 6.3.1 * Removes incorrect SMS instructions from README. diff --git a/packages/url_launcher/url_launcher/example/macos/Runner/DebugProfile.entitlements b/packages/url_launcher/url_launcher/example/macos/Runner/DebugProfile.entitlements index e635cd9a4bf4..dddb8a30c851 100644 --- a/packages/url_launcher/url_launcher/example/macos/Runner/DebugProfile.entitlements +++ b/packages/url_launcher/url_launcher/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/url_launcher/url_launcher/example/macos/Runner/Release.entitlements b/packages/url_launcher/url_launcher/example/macos/Runner/Release.entitlements index 0218c441b4e3..852fa1a4728a 100644 --- a/packages/url_launcher/url_launcher/example/macos/Runner/Release.entitlements +++ b/packages/url_launcher/url_launcher/example/macos/Runner/Release.entitlements @@ -3,7 +3,6 @@ com.apple.security.app-sandbox - - + diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index a20fb1f84d10..e3eae2544bf8 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the url_launcher plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 3b594e883fba..5845ac4927d6 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 6.3.1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/url_launcher/url_launcher_ios/CHANGELOG.md b/packages/url_launcher/url_launcher_ios/CHANGELOG.md index d0953fd61766..a7a283075d4c 100644 --- a/packages/url_launcher/url_launcher_ios/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_ios/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 6.3.2 * Updates to Pigeon v22. diff --git a/packages/url_launcher/url_launcher_ios/example/pubspec.yaml b/packages/url_launcher/url_launcher_ios/example/pubspec.yaml index 3e259987a104..0416298beaca 100644 --- a/packages/url_launcher/url_launcher_ios/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_ios/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the url_launcher plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_ios/pubspec.yaml b/packages/url_launcher/url_launcher_ios/pubspec.yaml index 2069aa0931e3..4d11751a4a99 100644 --- a/packages/url_launcher/url_launcher_ios/pubspec.yaml +++ b/packages/url_launcher/url_launcher_ios/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 6.3.2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/url_launcher/url_launcher_linux/CHANGELOG.md b/packages/url_launcher/url_launcher_linux/CHANGELOG.md index 7ba11785c092..8f20acefde26 100644 --- a/packages/url_launcher/url_launcher_linux/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_linux/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 3.2.1 * Updates Pigeon to resolve a compilation failure with some versions of glib. diff --git a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml index 0a3b93f5c21b..e9dfe5651d8b 100644 --- a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the url_launcher plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_linux/pubspec.yaml b/packages/url_launcher/url_launcher_linux/pubspec.yaml index fa1b45191043..60037197e8f2 100644 --- a/packages/url_launcher/url_launcher_linux/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 3.2.1 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/url_launcher/url_launcher_macos/CHANGELOG.md b/packages/url_launcher/url_launcher_macos/CHANGELOG.md index 5da4d7951ec7..72aef5b6a002 100644 --- a/packages/url_launcher/url_launcher_macos/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 3.2.2 * Updates to Pigeon v22. diff --git a/packages/url_launcher/url_launcher_macos/example/macos/Runner/DebugProfile.entitlements b/packages/url_launcher/url_launcher_macos/example/macos/Runner/DebugProfile.entitlements index e635cd9a4bf4..dddb8a30c851 100644 --- a/packages/url_launcher/url_launcher_macos/example/macos/Runner/DebugProfile.entitlements +++ b/packages/url_launcher/url_launcher_macos/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.server diff --git a/packages/url_launcher/url_launcher_macos/example/macos/Runner/Release.entitlements b/packages/url_launcher/url_launcher_macos/example/macos/Runner/Release.entitlements index 0218c441b4e3..852fa1a4728a 100644 --- a/packages/url_launcher/url_launcher_macos/example/macos/Runner/Release.entitlements +++ b/packages/url_launcher/url_launcher_macos/example/macos/Runner/Release.entitlements @@ -3,7 +3,6 @@ com.apple.security.app-sandbox - - + diff --git a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml index 4fa890968d27..9ae117df8c0a 100644 --- a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the url_launcher plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_macos/pubspec.yaml b/packages/url_launcher/url_launcher_macos/pubspec.yaml index 7f6505c702b5..fc9409038602 100644 --- a/packages/url_launcher/url_launcher_macos/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 3.2.2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md index 680ce1a23db8..521687f1a78f 100644 --- a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 2.3.2 diff --git a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml index b31502a3d6c5..837277694458 100644 --- a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml +++ b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.3.2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md index b891293c005f..0baf6389c8b9 100644 --- a/packages/url_launcher/url_launcher_web/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.3.3 * Changes `launchUrl` so it always returns `true`, except for disallowed URL schemes. diff --git a/packages/url_launcher/url_launcher_web/example/pubspec.yaml b/packages/url_launcher/url_launcher_web/example/pubspec.yaml index 606f477b4a40..a70f27951b9e 100644 --- a/packages/url_launcher/url_launcher_web/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/example/pubspec.yaml @@ -2,8 +2,8 @@ name: regular_integration_tests publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 3730a4dd90e4..7b9068d19153 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.3.3 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/url_launcher/url_launcher_windows/CHANGELOG.md b/packages/url_launcher/url_launcher_windows/CHANGELOG.md index 668ee6eff6ac..05a2acbd6b16 100644 --- a/packages/url_launcher/url_launcher_windows/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 3.1.3 * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. diff --git a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml index d76188c383ec..f00c0ba76132 100644 --- a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates the Windows implementation of the url_launcher plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_windows/pubspec.yaml b/packages/url_launcher/url_launcher_windows/pubspec.yaml index 629e9dc71963..5c81c7786754 100644 --- a/packages/url_launcher/url_launcher_windows/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 3.1.3 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 5e448be001b3..22a4bc0ed80a 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.9.2 * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. diff --git a/packages/video_player/video_player/example/macos/Runner/DebugProfile.entitlements b/packages/video_player/video_player/example/macos/Runner/DebugProfile.entitlements index c8f2dc5c7362..3ba6c1266f21 100644 --- a/packages/video_player/video_player/example/macos/Runner/DebugProfile.entitlements +++ b/packages/video_player/video_player/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.client diff --git a/packages/video_player/video_player/example/macos/Runner/Release.entitlements b/packages/video_player/video_player/example/macos/Runner/Release.entitlements index 5fe13922aa58..ee95ab7e582d 100644 --- a/packages/video_player/video_player/example/macos/Runner/Release.entitlements +++ b/packages/video_player/video_player/example/macos/Runner/Release.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.network.client diff --git a/packages/video_player/video_player/example/pubspec.yaml b/packages/video_player/video_player/example/pubspec.yaml index 25f812abeeee..5755db029dd6 100644 --- a/packages/video_player/video_player/example/pubspec.yaml +++ b/packages/video_player/video_player/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the video_player plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index 6e8b92684d7c..c19f6c6f77ca 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -6,8 +6,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.9.2 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/video_player/video_player_avfoundation/CHANGELOG.md b/packages/video_player/video_player_avfoundation/CHANGELOG.md index eff85341000b..0f0b4dabac26 100644 --- a/packages/video_player/video_player_avfoundation/CHANGELOG.md +++ b/packages/video_player/video_player_avfoundation/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 2.6.5 * Bugfix to allow the audio-only HLS (.m3u8) on iOS. diff --git a/packages/video_player/video_player_avfoundation/example/macos/Runner/DebugProfile.entitlements b/packages/video_player/video_player_avfoundation/example/macos/Runner/DebugProfile.entitlements index c8f2dc5c7362..3ba6c1266f21 100644 --- a/packages/video_player/video_player_avfoundation/example/macos/Runner/DebugProfile.entitlements +++ b/packages/video_player/video_player_avfoundation/example/macos/Runner/DebugProfile.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.cs.allow-jit com.apple.security.network.client diff --git a/packages/video_player/video_player_avfoundation/example/macos/Runner/Release.entitlements b/packages/video_player/video_player_avfoundation/example/macos/Runner/Release.entitlements index 5fe13922aa58..ee95ab7e582d 100644 --- a/packages/video_player/video_player_avfoundation/example/macos/Runner/Release.entitlements +++ b/packages/video_player/video_player_avfoundation/example/macos/Runner/Release.entitlements @@ -3,8 +3,7 @@ com.apple.security.app-sandbox - - + com.apple.security.network.client diff --git a/packages/video_player/video_player_avfoundation/example/pubspec.yaml b/packages/video_player/video_player_avfoundation/example/pubspec.yaml index ea24144202f9..ab457872a0d8 100644 --- a/packages/video_player/video_player_avfoundation/example/pubspec.yaml +++ b/packages/video_player/video_player_avfoundation/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the video_player plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/video_player/video_player_avfoundation/pubspec.yaml b/packages/video_player/video_player_avfoundation/pubspec.yaml index 632e59f60fd5..e6e72fefab27 100644 --- a/packages/video_player/video_player_avfoundation/pubspec.yaml +++ b/packages/video_player/video_player_avfoundation/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.6.5 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" flutter: plugin: diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md index 471cde8298d4..3c1e70fec40a 100644 --- a/packages/video_player/video_player_platform_interface/CHANGELOG.md +++ b/packages/video_player/video_player_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 6.2.3 * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. diff --git a/packages/video_player/video_player_platform_interface/pubspec.yaml b/packages/video_player/video_player_platform_interface/pubspec.yaml index 7ed49e9e2d3d..6a0f1e65c210 100644 --- a/packages/video_player/video_player_platform_interface/pubspec.yaml +++ b/packages/video_player/video_player_platform_interface/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 6.2.3 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/web_benchmarks/CHANGELOG.md b/packages/web_benchmarks/CHANGELOG.md index 934507cfbde3..b724d0ef2f80 100644 --- a/packages/web_benchmarks/CHANGELOG.md +++ b/packages/web_benchmarks/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 4.0.0 * **Breaking change:** Removes `CompilationOptions.renderer` and the diff --git a/packages/web_benchmarks/pubspec.yaml b/packages/web_benchmarks/pubspec.yaml index ed3ca89f9ffa..3c10d9047153 100644 --- a/packages/web_benchmarks/pubspec.yaml +++ b/packages/web_benchmarks/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 4.0.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: collection: ^1.18.0 diff --git a/packages/web_benchmarks/testing/test_app/pubspec.yaml b/packages/web_benchmarks/testing/test_app/pubspec.yaml index 902f1e0ba9cb..27458c3d704f 100644 --- a/packages/web_benchmarks/testing/test_app/pubspec.yaml +++ b/packages/web_benchmarks/testing/test_app/pubspec.yaml @@ -6,7 +6,7 @@ publish_to: 'none' version: 1.0.0+1 environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: flutter: diff --git a/packages/webview_flutter/webview_flutter/CHANGELOG.md b/packages/webview_flutter/webview_flutter/CHANGELOG.md index f52c4cbce1ce..1d95b3b902a4 100644 --- a/packages/webview_flutter/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 4.10.0 * Updates minimum supported `webview_flutter_android` from 3.16.0 to 4.0.0. diff --git a/packages/webview_flutter/webview_flutter/example/pubspec.yaml b/packages/webview_flutter/webview_flutter/example/pubspec.yaml index 1eb34f957ea0..e6152419a9a9 100644 --- a/packages/webview_flutter/webview_flutter/example/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the webview_flutter plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md index 16dcfd07e48c..24633e85bd86 100644 --- a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.2.0 + +* Adds support for configuring file access permissions. See `AndroidWebViewController.setAllowFileAccess`. + ## 4.1.0 * Updates internal API wrapper to use `ProxyApi`s. diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart index c250a87d36a9..3cde232ca9f9 100644 --- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart +++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart @@ -353,6 +353,13 @@ class AndroidWebViewController extends PlatformWebViewController { void Function(ScrollPositionChange scrollPositionChange)? _onScrollPositionChangedCallback; + /// Sets the file access permission for the web view. + /// + /// The default value is true for apps targeting API 29 and below, and false + /// when targeting API 30 and above. + Future setAllowFileAccess(bool allow) => + _webView.settings.setAllowFileAccess(allow); + /// Whether to enable the platform's webview content debugging tools. /// /// Defaults to false. diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml index 4ff9b6166a6d..44f19b2af19c 100644 --- a/packages/webview_flutter/webview_flutter_android/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_android/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_android description: A Flutter plugin that provides a WebView widget on Android. repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 4.1.0 +version: 4.2.0 environment: sdk: ^3.5.0 diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart index 6879c33253e7..167b660aa53f 100644 --- a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart +++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart @@ -1495,6 +1495,22 @@ void main() { expect(await controller.getUserAgent(), userAgent); }); + + test('setAllowFileAccess', () async { + final MockWebView mockWebView = MockWebView(); + final MockWebSettings mockSettings = MockWebSettings(); + final AndroidWebViewController controller = createControllerWithMocks( + mockWebView: mockWebView, + mockSettings: mockSettings, + ); + + clearInteractions(mockWebView); + + await controller.setAllowFileAccess(true); + + verify(mockWebView.settings).called(1); + verify(mockSettings.setAllowFileAccess(true)).called(1); + }); }); test('setMediaPlaybackRequiresUserGesture', () async { diff --git a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md index f6b57b5e1a5c..5b3a1ba25b39 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 2.10.0 diff --git a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml index c7cb7f96eba1..6bfcad34aa5e 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml @@ -7,8 +7,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 2.10.0 environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md index 11e104865443..0cd1ce8e29be 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 3.16.3 * Fixes re-registering existing channels while removing Javascript channels. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/example/pubspec.yaml index 2212808e098e..051e60afa666 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the webview_flutter_wkwebview plugin. publish_to: none environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/xdg_directories/CHANGELOG.md b/packages/xdg_directories/CHANGELOG.md index caad99371e95..bd23eb2d093a 100644 --- a/packages/xdg_directories/CHANGELOG.md +++ b/packages/xdg_directories/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 1.1.0 * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. diff --git a/packages/xdg_directories/example/pubspec.yaml b/packages/xdg_directories/example/pubspec.yaml index 6371986d179c..1f0314a685e3 100644 --- a/packages/xdg_directories/example/pubspec.yaml +++ b/packages/xdg_directories/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the xdg_directories package. publish_to: 'none' environment: - sdk: ^3.3.0 - flutter: ">=3.19.0" + sdk: ^3.4.0 + flutter: ">=3.22.0" dependencies: flutter: diff --git a/packages/xdg_directories/pubspec.yaml b/packages/xdg_directories/pubspec.yaml index 732bf2cd3f44..0983195a0a37 100644 --- a/packages/xdg_directories/pubspec.yaml +++ b/packages/xdg_directories/pubspec.yaml @@ -5,7 +5,7 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.1.0 environment: - sdk: ^3.3.0 + sdk: ^3.4.0 platforms: linux: diff --git a/script/tool/lib/src/common/core.dart b/script/tool/lib/src/common/core.dart index 9fef751ab56d..57b48252241d 100644 --- a/script/tool/lib/src/common/core.dart +++ b/script/tool/lib/src/common/core.dart @@ -85,6 +85,8 @@ final Map _dartSdkForFlutterSdk = { Version(3, 22, 0): Version(3, 4, 0), Version(3, 22, 3): Version(3, 4, 4), Version(3, 24, 0): Version(3, 5, 0), + Version(3, 24, 5): Version(3, 5, 4), + Version(3, 27, 0): Version(3, 6, 0), }; /// Returns the version of the Dart SDK that shipped with the given Flutter diff --git a/third_party/packages/cupertino_icons/CHANGELOG.md b/third_party/packages/cupertino_icons/CHANGELOG.md index 447d622436e4..49e20a6a5f52 100644 --- a/third_party/packages/cupertino_icons/CHANGELOG.md +++ b/third_party/packages/cupertino_icons/CHANGELOG.md @@ -1,6 +1,6 @@ ## NEXT -* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 1.0.8 diff --git a/third_party/packages/cupertino_icons/pubspec.yaml b/third_party/packages/cupertino_icons/pubspec.yaml index 76e5962fd4e1..9ad4317bdea0 100644 --- a/third_party/packages/cupertino_icons/pubspec.yaml +++ b/third_party/packages/cupertino_icons/pubspec.yaml @@ -6,7 +6,7 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.0.8 environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dev_dependencies: collection: ^1.18.0 diff --git a/third_party/packages/path_parsing/CHANGELOG.md b/third_party/packages/path_parsing/CHANGELOG.md index 976dbd012355..f543e817124b 100644 --- a/third_party/packages/path_parsing/CHANGELOG.md +++ b/third_party/packages/path_parsing/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. + ## 1.1.0 * Deprecates top-level utility functions `blendPoints` and `reflectedPoint` and diff --git a/third_party/packages/path_parsing/example/pubspec.yaml b/third_party/packages/path_parsing/example/pubspec.yaml index dd9a6eef8dcb..02b1e094156e 100644 --- a/third_party/packages/path_parsing/example/pubspec.yaml +++ b/third_party/packages/path_parsing/example/pubspec.yaml @@ -2,7 +2,7 @@ name: path_parsing_example publish_to: none environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: path_parsing: diff --git a/third_party/packages/path_parsing/pubspec.yaml b/third_party/packages/path_parsing/pubspec.yaml index ae99c4dffc07..3c11104989f8 100644 --- a/third_party/packages/path_parsing/pubspec.yaml +++ b/third_party/packages/path_parsing/pubspec.yaml @@ -6,7 +6,7 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 1.1.0 environment: - sdk: ^3.3.0 + sdk: ^3.4.0 dependencies: meta: ^1.3.0